Whamcloud - gitweb
LU-6142 tests: Add missing /tmp/target2 under cleanup_src_tgt
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47 fi
48
49 # skip the grant tests for ARM until they are fixed
50 if [[ $(uname -m) = aarch64 ]]; then
51         always_except LU-11671 45
52 fi
53
54 # skip nfs tests on kernels >= 4.12.0 until they are fixed
55 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
56         always_except LU-12661 817
57 fi
58 # skip cgroup tests on RHEL8.1 kernels until they are fixed
59 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
60       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
61         always_except LU-13063 411a
62 fi
63
64 # skip cgroup tests for kernels < v4.18.0
65 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
66         always_except LU-13063 411b
67 fi
68
69 #                                  5              12     8   12  15   (min)"
70 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
71
72 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
73         #                                               13    (min)"
74         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
75 fi
76
77 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
78         always_except LU-1941 130b 130c 130d 130e 130f 130g
79         always_except LU-9054 312
80 fi
81
82 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
83
84 # Get the SLES distro version
85 #
86 # Returns a version string that should only be used in comparing
87 # strings returned by version_code()
88 sles_version_code()
89 {
90         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
91
92         # All SuSE Linux versions have one decimal. version_code expects two
93         local sles_version=$version.0
94         version_code $sles_version
95 }
96
97 # Check if we are running on Ubuntu or SLES so we can make decisions on
98 # what tests to run
99 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
100         sles_version=$(sles_version_code)
101         [ $sles_version -lt $(version_code 11.4.0) ] &&
102                 always_except LU-4341 170
103
104         [ $sles_version -lt $(version_code 12.0.0) ] &&
105                 always_except LU-3703 234
106 elif [ -r /etc/os-release ]; then
107         if grep -qi ubuntu /etc/os-release; then
108                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
109                                                 -e 's/^VERSION=//p' \
110                                                 /etc/os-release |
111                                                 awk '{ print $1 }'))
112
113                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
114                         always_except LU-10366 410
115                 fi
116         fi
117 fi
118
119 build_test_filter
120 FAIL_ON_ERROR=false
121
122 cleanup() {
123         echo -n "cln.."
124         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
125         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
126 }
127 setup() {
128         echo -n "mnt.."
129         load_modules
130         setupall || exit 10
131         echo "done"
132 }
133
134 check_swap_layouts_support()
135 {
136         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
137                 skip "Does not support layout lock."
138 }
139
140 check_swap_layout_no_dom()
141 {
142         local FOLDER=$1
143         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
144         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
145 }
146
147 check_and_setup_lustre
148 DIR=${DIR:-$MOUNT}
149 assert_DIR
150
151 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
152
153 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
154 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
155 rm -rf $DIR/[Rdfs][0-9]*
156
157 # $RUNAS_ID may get set incorrectly somewhere else
158 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
159         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
160
161 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
162
163 if [ "${ONLY}" = "MOUNT" ] ; then
164         echo "Lustre is up, please go on"
165         exit
166 fi
167
168 echo "preparing for tests involving mounts"
169 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
170 touch $EXT2_DEV
171 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
172 echo # add a newline after mke2fs.
173
174 umask 077
175
176 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
177
178 # ensure all internal functions know we want full debug
179 export PTLDEBUG=all
180 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
181
182 test_0a() {
183         touch $DIR/$tfile
184         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
185         rm $DIR/$tfile
186         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
187 }
188 run_test 0a "touch; rm ====================="
189
190 test_0b() {
191         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
192         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
193 }
194 run_test 0b "chmod 0755 $DIR ============================="
195
196 test_0c() {
197         $LCTL get_param mdc.*.import | grep "state: FULL" ||
198                 error "import not FULL"
199         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
200                 error "bad target"
201 }
202 run_test 0c "check import proc"
203
204 test_0d() { # LU-3397
205         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
206                 skip "proc exports not supported before 2.10.57"
207
208         local mgs_exp="mgs.MGS.exports"
209         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
210         local exp_client_nid
211         local exp_client_version
212         local exp_val
213         local imp_val
214         local temp_imp=$DIR/$tfile.import
215         local temp_exp=$DIR/$tfile.export
216
217         # save mgc import file to $temp_imp
218         $LCTL get_param mgc.*.import | tee $temp_imp
219         # Check if client uuid is found in MGS export
220         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
221                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
222                         $client_uuid ] &&
223                         break;
224         done
225         # save mgs export file to $temp_exp
226         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
227
228         # Compare the value of field "connect_flags"
229         imp_val=$(grep "connect_flags" $temp_imp)
230         exp_val=$(grep "connect_flags" $temp_exp)
231         [ "$exp_val" == "$imp_val" ] ||
232                 error "export flags '$exp_val' != import flags '$imp_val'"
233
234         # Compare client versions.  Only compare top-3 fields for compatibility
235         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
236         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
237         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
238         [ "$exp_val" == "$imp_val" ] ||
239                 error "exp version '$exp_client_version'($exp_val) != " \
240                         "'$(lustre_build_version client)'($imp_val)"
241 }
242 run_test 0d "check export proc ============================="
243
244 test_0e() { # LU-13417
245         (( $MDSCOUNT > 1 )) ||
246                 skip "We need at least 2 MDTs for this test"
247
248         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
249                 skip "Need server version at least 2.14.51"
250
251         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
252         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
253
254         [ $default_lmv_count -eq 1 ] ||
255                 error "$MOUNT default stripe count $default_lmv_count"
256
257         [ $default_lmv_index -eq -1 ] ||
258                 error "$MOUNT default stripe index $default_lmv_index"
259
260         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
261         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
262
263         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
264         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
265
266         [ $mdt_index1 -eq $mdt_index2 ] &&
267                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
268
269         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
270 }
271 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
272
273 test_1() {
274         test_mkdir $DIR/$tdir
275         test_mkdir $DIR/$tdir/d2
276         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
277         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
278         rmdir $DIR/$tdir/d2
279         rmdir $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
281 }
282 run_test 1 "mkdir; remkdir; rmdir"
283
284 test_2() {
285         test_mkdir $DIR/$tdir
286         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
287         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
288         rm -r $DIR/$tdir
289         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
290 }
291 run_test 2 "mkdir; touch; rmdir; check file"
292
293 test_3() {
294         test_mkdir $DIR/$tdir
295         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
296         touch $DIR/$tdir/$tfile
297         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
298         rm -r $DIR/$tdir
299         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
300 }
301 run_test 3 "mkdir; touch; rmdir; check dir"
302
303 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
304 test_4() {
305         test_mkdir -i 1 $DIR/$tdir
306
307         touch $DIR/$tdir/$tfile ||
308                 error "Create file under remote directory failed"
309
310         rmdir $DIR/$tdir &&
311                 error "Expect error removing in-use dir $DIR/$tdir"
312
313         test -d $DIR/$tdir || error "Remote directory disappeared"
314
315         rm -rf $DIR/$tdir || error "remove remote dir error"
316 }
317 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
318
319 test_5() {
320         test_mkdir $DIR/$tdir
321         test_mkdir $DIR/$tdir/d2
322         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
323         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
324         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
325 }
326 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
327
328 test_6a() {
329         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
330         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
331         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
332                 error "$tfile does not have perm 0666 or UID $UID"
333         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
334         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
335                 error "$tfile should be 0666 and owned by UID $UID"
336 }
337 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
338
339 test_6c() {
340         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
341
342         touch $DIR/$tfile
343         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
344         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
345                 error "$tfile should be owned by UID $RUNAS_ID"
346         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
347         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
348                 error "$tfile should be owned by UID $RUNAS_ID"
349 }
350 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
351
352 test_6e() {
353         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
354
355         touch $DIR/$tfile
356         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
357         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
358                 error "$tfile should be owned by GID $UID"
359         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
360         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
362 }
363 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
364
365 test_6g() {
366         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
367
368         test_mkdir $DIR/$tdir
369         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
370         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
371         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
372         test_mkdir $DIR/$tdir/d/subdir
373         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
374                 error "$tdir/d/subdir should be GID $RUNAS_GID"
375         if [[ $MDSCOUNT -gt 1 ]]; then
376                 # check remote dir sgid inherite
377                 $LFS mkdir -i 0 $DIR/$tdir.local ||
378                         error "mkdir $tdir.local failed"
379                 chmod g+s $DIR/$tdir.local ||
380                         error "chmod $tdir.local failed"
381                 chgrp $RUNAS_GID $DIR/$tdir.local ||
382                         error "chgrp $tdir.local failed"
383                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
384                         error "mkdir $tdir.remote failed"
385                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
387                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
388                         error "$tdir.remote should be mode 02755"
389         fi
390 }
391 run_test 6g "verify new dir in sgid dir inherits group"
392
393 test_6h() { # bug 7331
394         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
395
396         touch $DIR/$tfile || error "touch failed"
397         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
398         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
399                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
400         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
401                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
402 }
403 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
404
405 test_7a() {
406         test_mkdir $DIR/$tdir
407         $MCREATE $DIR/$tdir/$tfile
408         chmod 0666 $DIR/$tdir/$tfile
409         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
410                 error "$tdir/$tfile should be mode 0666"
411 }
412 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
413
414 test_7b() {
415         if [ ! -d $DIR/$tdir ]; then
416                 test_mkdir $DIR/$tdir
417         fi
418         $MCREATE $DIR/$tdir/$tfile
419         echo -n foo > $DIR/$tdir/$tfile
420         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
421         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
422 }
423 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
424
425 test_8() {
426         test_mkdir $DIR/$tdir
427         touch $DIR/$tdir/$tfile
428         chmod 0666 $DIR/$tdir/$tfile
429         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
430                 error "$tfile mode not 0666"
431 }
432 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
433
434 test_9() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         test_mkdir $DIR/$tdir/d2/d3
438         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
439 }
440 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
441
442 test_10() {
443         test_mkdir $DIR/$tdir
444         test_mkdir $DIR/$tdir/d2
445         touch $DIR/$tdir/d2/$tfile
446         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
447                 error "$tdir/d2/$tfile not a file"
448 }
449 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
450
451 test_11() {
452         test_mkdir $DIR/$tdir
453         test_mkdir $DIR/$tdir/d2
454         chmod 0666 $DIR/$tdir/d2
455         chmod 0705 $DIR/$tdir/d2
456         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
457                 error "$tdir/d2 mode not 0705"
458 }
459 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
460
461 test_12() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         chmod 0666 $DIR/$tdir/$tfile
465         chmod 0654 $DIR/$tdir/$tfile
466         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
467                 error "$tdir/d2 mode not 0654"
468 }
469 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
470
471 test_13() {
472         test_mkdir $DIR/$tdir
473         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
474         >  $DIR/$tdir/$tfile
475         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
476                 error "$tdir/$tfile size not 0 after truncate"
477 }
478 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
479
480 test_14() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         rm $DIR/$tdir/$tfile
484         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
485 }
486 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
487
488 test_15() {
489         test_mkdir $DIR/$tdir
490         touch $DIR/$tdir/$tfile
491         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
492         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
493                 error "$tdir/${tfile_2} not a file after rename"
494         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
495 }
496 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
497
498 test_16() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         rm -rf $DIR/$tdir/$tfile
502         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
503 }
504 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
505
506 test_17a() {
507         test_mkdir $DIR/$tdir
508         touch $DIR/$tdir/$tfile
509         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
510         ls -l $DIR/$tdir
511         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not a symlink"
513         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
514                 error "$tdir/l-exist not referencing a file"
515         rm -f $DIR/$tdir/l-exist
516         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
517 }
518 run_test 17a "symlinks: create, remove (real)"
519
520 test_17b() {
521         test_mkdir $DIR/$tdir
522         ln -s no-such-file $DIR/$tdir/l-dangle
523         ls -l $DIR/$tdir
524         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing no-such-file"
526         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
527                 error "$tdir/l-dangle not referencing non-existent file"
528         rm -f $DIR/$tdir/l-dangle
529         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
530 }
531 run_test 17b "symlinks: create, remove (dangling)"
532
533 test_17c() { # bug 3440 - don't save failed open RPC for replay
534         test_mkdir $DIR/$tdir
535         ln -s foo $DIR/$tdir/$tfile
536         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
537 }
538 run_test 17c "symlinks: open dangling (should return error)"
539
540 test_17d() {
541         test_mkdir $DIR/$tdir
542         ln -s foo $DIR/$tdir/$tfile
543         touch $DIR/$tdir/$tfile || error "creating to new symlink"
544 }
545 run_test 17d "symlinks: create dangling"
546
547 test_17e() {
548         test_mkdir $DIR/$tdir
549         local foo=$DIR/$tdir/$tfile
550         ln -s $foo $foo || error "create symlink failed"
551         ls -l $foo || error "ls -l failed"
552         ls $foo && error "ls not failed" || true
553 }
554 run_test 17e "symlinks: create recursive symlink (should return error)"
555
556 test_17f() {
557         test_mkdir $DIR/$tdir
558         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
563         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
564         ls -l  $DIR/$tdir
565 }
566 run_test 17f "symlinks: long and very long symlink name"
567
568 # str_repeat(S, N) generate a string that is string S repeated N times
569 str_repeat() {
570         local s=$1
571         local n=$2
572         local ret=''
573         while [ $((n -= 1)) -ge 0 ]; do
574                 ret=$ret$s
575         done
576         echo $ret
577 }
578
579 # Long symlinks and LU-2241
580 test_17g() {
581         test_mkdir $DIR/$tdir
582         local TESTS="59 60 61 4094 4095"
583
584         # Fix for inode size boundary in 2.1.4
585         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
586                 TESTS="4094 4095"
587
588         # Patch not applied to 2.2 or 2.3 branches
589         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
590         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
591                 TESTS="4094 4095"
592
593         for i in $TESTS; do
594                 local SYMNAME=$(str_repeat 'x' $i)
595                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
596                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
597         done
598 }
599 run_test 17g "symlinks: really long symlink name and inode boundaries"
600
601 test_17h() { #bug 17378
602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
603         remote_mds_nodsh && skip "remote MDS with nodsh"
604
605         local mdt_idx
606
607         test_mkdir $DIR/$tdir
608         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
609         $LFS setstripe -c -1 $DIR/$tdir
610         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
611         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
612         touch $DIR/$tdir/$tfile || true
613 }
614 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
615
616 test_17i() { #bug 20018
617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
618         remote_mds_nodsh && skip "remote MDS with nodsh"
619
620         local foo=$DIR/$tdir/$tfile
621         local mdt_idx
622
623         test_mkdir -c1 $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         ln -s $foo $foo || error "create symlink failed"
626 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
628         ls -l $foo && error "error not detected"
629         return 0
630 }
631 run_test 17i "don't panic on short symlink (should return error)"
632
633 test_17k() { #bug 22301
634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
635         [[ -z "$(which rsync 2>/dev/null)" ]] &&
636                 skip "no rsync command"
637         rsync --help | grep -q xattr ||
638                 skip_env "$(rsync --version | head -n1) does not support xattrs"
639         test_mkdir $DIR/$tdir
640         test_mkdir $DIR/$tdir.new
641         touch $DIR/$tdir/$tfile
642         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
643         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
644                 error "rsync failed with xattrs enabled"
645 }
646 run_test 17k "symlinks: rsync with xattrs enabled"
647
648 test_17l() { # LU-279
649         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
650                 skip "no getfattr command"
651
652         test_mkdir $DIR/$tdir
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
656                 # -h to not follow symlinks. -m '' to list all the xattrs.
657                 # grep to remove first line: '# file: $path'.
658                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
659                 do
660                         lgetxattr_size_check $path $xattr ||
661                                 error "lgetxattr_size_check $path $xattr failed"
662                 done
663         done
664 }
665 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
666
667 # LU-1540
668 test_17m() {
669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
670         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
671         remote_mds_nodsh && skip "remote MDS with nodsh"
672         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
673         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
674                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
675
676         local short_sym="0123456789"
677         local wdir=$DIR/$tdir
678         local i
679
680         test_mkdir $wdir
681         long_sym=$short_sym
682         # create a long symlink file
683         for ((i = 0; i < 4; ++i)); do
684                 long_sym=${long_sym}${long_sym}
685         done
686
687         echo "create 512 short and long symlink files under $wdir"
688         for ((i = 0; i < 256; ++i)); do
689                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
690                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
691         done
692
693         echo "erase them"
694         rm -f $wdir/*
695         sync
696         wait_delete_completed
697
698         echo "recreate the 512 symlink files with a shorter string"
699         for ((i = 0; i < 512; ++i)); do
700                 # rewrite the symlink file with a shorter string
701                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
702                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
703         done
704
705         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
706
707         echo "stop and checking mds${mds_index}:"
708         # e2fsck should not return error
709         stop mds${mds_index}
710         local devname=$(mdsdevname $mds_index)
711         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
712         rc=$?
713
714         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
715                 error "start mds${mds_index} failed"
716         df $MOUNT > /dev/null 2>&1
717         [ $rc -eq 0 ] ||
718                 error "e2fsck detected error for short/long symlink: rc=$rc"
719         rm -f $wdir/*
720 }
721 run_test 17m "run e2fsck against MDT which contains short/long symlink"
722
723 check_fs_consistency_17n() {
724         local mdt_index
725         local rc=0
726
727         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
728         # so it only check MDT1/MDT2 instead of all of MDTs.
729         for mdt_index in 1 2; do
730                 # e2fsck should not return error
731                 stop mds${mdt_index}
732                 local devname=$(mdsdevname $mdt_index)
733                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
734                         rc=$((rc + $?))
735
736                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
737                         error "mount mds$mdt_index failed"
738                 df $MOUNT > /dev/null 2>&1
739         done
740         return $rc
741 }
742
743 test_17n() {
744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
746         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
747         remote_mds_nodsh && skip "remote MDS with nodsh"
748         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
749         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
750                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
751
752         local i
753
754         test_mkdir $DIR/$tdir
755         for ((i=0; i<10; i++)); do
756                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
757                         error "create remote dir error $i"
758                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
759                         error "create files under remote dir failed $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after create files under remote dir"
764
765         for ((i = 0; i < 10; i++)); do
766                 rm -rf $DIR/$tdir/remote_dir_${i} ||
767                         error "destroy remote dir error $i"
768         done
769
770         check_fs_consistency_17n ||
771                 error "e2fsck report error after unlink files under remote dir"
772
773         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
774                 skip "lustre < 2.4.50 does not support migrate mv"
775
776         for ((i = 0; i < 10; i++)); do
777                 mkdir -p $DIR/$tdir/remote_dir_${i}
778                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
779                         error "create files under remote dir failed $i"
780                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
781                         error "migrate remote dir error $i"
782         done
783         check_fs_consistency_17n || error "e2fsck report error after migration"
784
785         for ((i = 0; i < 10; i++)); do
786                 rm -rf $DIR/$tdir/remote_dir_${i} ||
787                         error "destroy remote dir error $i"
788         done
789
790         check_fs_consistency_17n || error "e2fsck report error after unlink"
791 }
792 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
793
794 test_17o() {
795         remote_mds_nodsh && skip "remote MDS with nodsh"
796         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
797                 skip "Need MDS version at least 2.3.64"
798
799         local wdir=$DIR/${tdir}o
800         local mdt_index
801         local rc=0
802
803         test_mkdir $wdir
804         touch $wdir/$tfile
805         mdt_index=$($LFS getstripe -m $wdir/$tfile)
806         mdt_index=$((mdt_index + 1))
807
808         cancel_lru_locks mdc
809         #fail mds will wait the failover finish then set
810         #following fail_loc to avoid interfer the recovery process.
811         fail mds${mdt_index}
812
813         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
814         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
815         ls -l $wdir/$tfile && rc=1
816         do_facet mds${mdt_index} lctl set_param fail_loc=0
817         [[ $rc -eq 0 ]] || error "stat file should fail"
818 }
819 run_test 17o "stat file with incompat LMA feature"
820
821 test_18() {
822         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
823         ls $DIR || error "Failed to ls $DIR: $?"
824 }
825 run_test 18 "touch .../f ; ls ... =============================="
826
827 test_19a() {
828         touch $DIR/$tfile
829         ls -l $DIR
830         rm $DIR/$tfile
831         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
832 }
833 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
834
835 test_19b() {
836         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
837 }
838 run_test 19b "ls -l .../f19 (should return error) =============="
839
840 test_19c() {
841         [ $RUNAS_ID -eq $UID ] &&
842                 skip_env "RUNAS_ID = UID = $UID -- skipping"
843
844         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
845 }
846 run_test 19c "$RUNAS touch .../f19 (should return error) =="
847
848 test_19d() {
849         cat $DIR/f19 && error || true
850 }
851 run_test 19d "cat .../f19 (should return error) =============="
852
853 test_20() {
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         touch $DIR/$tfile
859         rm $DIR/$tfile
860         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
861 }
862 run_test 20 "touch .../f ; ls -l ..."
863
864 test_21() {
865         test_mkdir $DIR/$tdir
866         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
867         ln -s dangle $DIR/$tdir/link
868         echo foo >> $DIR/$tdir/link
869         cat $DIR/$tdir/dangle
870         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
871         $CHECKSTAT -f -t file $DIR/$tdir/link ||
872                 error "$tdir/link not linked to a file"
873 }
874 run_test 21 "write to dangling link"
875
876 test_22() {
877         local wdir=$DIR/$tdir
878         test_mkdir $wdir
879         chown $RUNAS_ID:$RUNAS_GID $wdir
880         (cd $wdir || error "cd $wdir failed";
881                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
882                 $RUNAS tar xf -)
883         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
884         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
885         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
886                 error "checkstat -u failed"
887 }
888 run_test 22 "unpack tar archive as non-root user"
889
890 # was test_23
891 test_23a() {
892         test_mkdir $DIR/$tdir
893         local file=$DIR/$tdir/$tfile
894
895         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
896         openfile -f O_CREAT:O_EXCL $file &&
897                 error "$file recreate succeeded" || true
898 }
899 run_test 23a "O_CREAT|O_EXCL in subdir"
900
901 test_23b() { # bug 18988
902         test_mkdir $DIR/$tdir
903         local file=$DIR/$tdir/$tfile
904
905         rm -f $file
906         echo foo > $file || error "write filed"
907         echo bar >> $file || error "append filed"
908         $CHECKSTAT -s 8 $file || error "wrong size"
909         rm $file
910 }
911 run_test 23b "O_APPEND check"
912
913 # LU-9409, size with O_APPEND and tiny writes
914 test_23c() {
915         local file=$DIR/$tfile
916
917         # single dd
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
919         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
920         rm -f $file
921
922         # racing tiny writes
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
925         wait
926         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
927         rm -f $file
928
929         #racing tiny & normal writes
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
932         wait
933         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
934         rm -f $file
935
936         #racing tiny & normal writes 2, ugly numbers
937         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
938         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
939         wait
940         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
941         rm -f $file
942 }
943 run_test 23c "O_APPEND size checks for tiny writes"
944
945 # LU-11069 file offset is correct after appending writes
946 test_23d() {
947         local file=$DIR/$tfile
948         local offset
949
950         echo CentaurHauls > $file
951         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
952         if ((offset != 26)); then
953                 error "wrong offset, expected 26, got '$offset'"
954         fi
955 }
956 run_test 23d "file offset is correct after appending writes"
957
958 # rename sanity
959 test_24a() {
960         echo '-- same directory rename'
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.1
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
965 }
966 run_test 24a "rename file to non-existent target"
967
968 test_24b() {
969         test_mkdir $DIR/$tdir
970         touch $DIR/$tdir/$tfile.{1,2}
971         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
972         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
973         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
974 }
975 run_test 24b "rename file to existing target"
976
977 test_24c() {
978         test_mkdir $DIR/$tdir
979         test_mkdir $DIR/$tdir/d$testnum.1
980         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
981         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
982         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
983 }
984 run_test 24c "rename directory to non-existent target"
985
986 test_24d() {
987         test_mkdir -c1 $DIR/$tdir
988         test_mkdir -c1 $DIR/$tdir/d$testnum.1
989         test_mkdir -c1 $DIR/$tdir/d$testnum.2
990         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
991         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
992         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
993 }
994 run_test 24d "rename directory to existing target"
995
996 test_24e() {
997         echo '-- cross directory renames --'
998         test_mkdir $DIR/R5a
999         test_mkdir $DIR/R5b
1000         touch $DIR/R5a/f
1001         mv $DIR/R5a/f $DIR/R5b/g
1002         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1003         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1004 }
1005 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1006
1007 test_24f() {
1008         test_mkdir $DIR/R6a
1009         test_mkdir $DIR/R6b
1010         touch $DIR/R6a/f $DIR/R6b/g
1011         mv $DIR/R6a/f $DIR/R6b/g
1012         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1013         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1014 }
1015 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1016
1017 test_24g() {
1018         test_mkdir $DIR/R7a
1019         test_mkdir $DIR/R7b
1020         test_mkdir $DIR/R7a/d
1021         mv $DIR/R7a/d $DIR/R7b/e
1022         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1023         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1024 }
1025 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1026
1027 test_24h() {
1028         test_mkdir -c1 $DIR/R8a
1029         test_mkdir -c1 $DIR/R8b
1030         test_mkdir -c1 $DIR/R8a/d
1031         test_mkdir -c1 $DIR/R8b/e
1032         mrename $DIR/R8a/d $DIR/R8b/e
1033         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1034         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1035 }
1036 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1037
1038 test_24i() {
1039         echo "-- rename error cases"
1040         test_mkdir $DIR/R9
1041         test_mkdir $DIR/R9/a
1042         touch $DIR/R9/f
1043         mrename $DIR/R9/f $DIR/R9/a
1044         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1045         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1046         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1047 }
1048 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1049
1050 test_24j() {
1051         test_mkdir $DIR/R10
1052         mrename $DIR/R10/f $DIR/R10/g
1053         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1054         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1055         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1056 }
1057 run_test 24j "source does not exist ============================"
1058
1059 test_24k() {
1060         test_mkdir $DIR/R11a
1061         test_mkdir $DIR/R11a/d
1062         touch $DIR/R11a/f
1063         mv $DIR/R11a/f $DIR/R11a/d
1064         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1065         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1066 }
1067 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1068
1069 # bug 2429 - rename foo foo foo creates invalid file
1070 test_24l() {
1071         f="$DIR/f24l"
1072         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1073 }
1074 run_test 24l "Renaming a file to itself ========================"
1075
1076 test_24m() {
1077         f="$DIR/f24m"
1078         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1079         # on ext3 this does not remove either the source or target files
1080         # though the "expected" operation would be to remove the source
1081         $CHECKSTAT -t file ${f} || error "${f} missing"
1082         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1083 }
1084 run_test 24m "Renaming a file to a hard link to itself ========="
1085
1086 test_24n() {
1087     f="$DIR/f24n"
1088     # this stats the old file after it was renamed, so it should fail
1089     touch ${f}
1090     $CHECKSTAT ${f} || error "${f} missing"
1091     mv ${f} ${f}.rename
1092     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1093     $CHECKSTAT -a ${f} || error "${f} exists"
1094 }
1095 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1096
1097 test_24o() {
1098         test_mkdir $DIR/$tdir
1099         rename_many -s random -v -n 10 $DIR/$tdir
1100 }
1101 run_test 24o "rename of files during htree split"
1102
1103 test_24p() {
1104         test_mkdir $DIR/R12a
1105         test_mkdir $DIR/R12b
1106         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1107         mrename $DIR/R12a $DIR/R12b
1108         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1109         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1110         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1111         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1112 }
1113 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1114
1115 cleanup_multiop_pause() {
1116         trap 0
1117         kill -USR1 $MULTIPID
1118 }
1119
1120 test_24q() {
1121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1122
1123         test_mkdir $DIR/R13a
1124         test_mkdir $DIR/R13b
1125         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1126         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1127         MULTIPID=$!
1128
1129         trap cleanup_multiop_pause EXIT
1130         mrename $DIR/R13a $DIR/R13b
1131         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1132         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1133         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1134         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1135         cleanup_multiop_pause
1136         wait $MULTIPID || error "multiop close failed"
1137 }
1138 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1139
1140 test_24r() { #bug 3789
1141         test_mkdir $DIR/R14a
1142         test_mkdir $DIR/R14a/b
1143         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1145         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1146 }
1147 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1148
1149 test_24s() {
1150         test_mkdir $DIR/R15a
1151         test_mkdir $DIR/R15a/b
1152         test_mkdir $DIR/R15a/b/c
1153         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1154         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1155         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1156 }
1157 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1158
1159 test_24t() {
1160         test_mkdir $DIR/R16a
1161         test_mkdir $DIR/R16a/b
1162         test_mkdir $DIR/R16a/b/c
1163         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1164         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1165         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1166 }
1167 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1168
1169 test_24u() { # bug12192
1170         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1171         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1172 }
1173 run_test 24u "create stripe file"
1174
1175 simple_cleanup_common() {
1176         local createmany=$1
1177         local rc=0
1178
1179         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1180
1181         local start=$SECONDS
1182
1183         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1184         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1185         rc=$?
1186         wait_delete_completed
1187         echo "cleanup time $((SECONDS - start))"
1188         return $rc
1189 }
1190
1191 max_pages_per_rpc() {
1192         local mdtname="$(printf "MDT%04x" ${1:-0})"
1193         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1194 }
1195
1196 test_24v() {
1197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1198
1199         local nrfiles=${COUNT:-100000}
1200         local fname="$DIR/$tdir/$tfile"
1201
1202         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1203         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1204
1205         test_mkdir "$(dirname $fname)"
1206         # assume MDT0000 has the fewest inodes
1207         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1208         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1209         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1210
1211         stack_trap "simple_cleanup_common $nrfiles"
1212
1213         createmany -m "$fname" $nrfiles
1214
1215         cancel_lru_locks mdc
1216         lctl set_param mdc.*.stats clear
1217
1218         # was previously test_24D: LU-6101
1219         # readdir() returns correct number of entries after cursor reload
1220         local num_ls=$(ls $DIR/$tdir | wc -l)
1221         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1222         local num_all=$(ls -a $DIR/$tdir | wc -l)
1223         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1224                 [ $num_all -ne $((nrfiles + 2)) ]; then
1225                         error "Expected $nrfiles files, got $num_ls " \
1226                                 "($num_uniq unique $num_all .&..)"
1227         fi
1228         # LU-5 large readdir
1229         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1230         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1231         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1232         # take into account of overhead in lu_dirpage header and end mark in
1233         # each page, plus one in rpc_num calculation.
1234         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1235         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1236         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1237         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1238         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1239         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1240         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1241         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1242                 error "large readdir doesn't take effect: " \
1243                       "$mds_readpage should be about $rpc_max"
1244 }
1245 run_test 24v "list large directory (test hash collision, b=17560)"
1246
1247 test_24w() { # bug21506
1248         SZ1=234852
1249         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1250         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1251         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1252         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1253         [[ "$SZ1" -eq "$SZ2" ]] ||
1254                 error "Error reading at the end of the file $tfile"
1255 }
1256 run_test 24w "Reading a file larger than 4Gb"
1257
1258 test_24x() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1262                 skip "Need MDS version at least 2.7.56"
1263
1264         local MDTIDX=1
1265         local remote_dir=$DIR/$tdir/remote_dir
1266
1267         test_mkdir $DIR/$tdir
1268         $LFS mkdir -i $MDTIDX $remote_dir ||
1269                 error "create remote directory failed"
1270
1271         test_mkdir $DIR/$tdir/src_dir
1272         touch $DIR/$tdir/src_file
1273         test_mkdir $remote_dir/tgt_dir
1274         touch $remote_dir/tgt_file
1275
1276         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1277                 error "rename dir cross MDT failed!"
1278
1279         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1280                 error "rename file cross MDT failed!"
1281
1282         touch $DIR/$tdir/ln_file
1283         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1284                 error "ln file cross MDT failed"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24x "cross MDT rename/link"
1289
1290 test_24y() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1293
1294         local remote_dir=$DIR/$tdir/remote_dir
1295         local mdtidx=1
1296
1297         test_mkdir $DIR/$tdir
1298         $LFS mkdir -i $mdtidx $remote_dir ||
1299                 error "create remote directory failed"
1300
1301         test_mkdir $remote_dir/src_dir
1302         touch $remote_dir/src_file
1303         test_mkdir $remote_dir/tgt_dir
1304         touch $remote_dir/tgt_file
1305
1306         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1307                 error "rename subdir in the same remote dir failed!"
1308
1309         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1310                 error "rename files in the same remote dir failed!"
1311
1312         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1313                 error "link files in the same remote dir failed!"
1314
1315         rm -rf $DIR/$tdir || error "Can not delete directories"
1316 }
1317 run_test 24y "rename/link on the same dir should succeed"
1318
1319 test_24z() {
1320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1321         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1322                 skip "Need MDS version at least 2.12.51"
1323
1324         local index
1325
1326         for index in 0 1; do
1327                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1328                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1329         done
1330
1331         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1332
1333         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1334         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1335
1336         local mdts=$(comma_list $(mdts_nodes))
1337
1338         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1339         stack_trap "do_nodes $mdts $LCTL \
1340                 set_param mdt.*.enable_remote_rename=1" EXIT
1341
1342         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1343
1344         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1345         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1346 }
1347 run_test 24z "cross-MDT rename is done as cp"
1348
1349 test_24A() { # LU-3182
1350         local NFILES=5000
1351
1352         test_mkdir $DIR/$tdir
1353         stack_trap "simple_cleanup_common $NFILES"
1354         createmany -m $DIR/$tdir/$tfile $NFILES
1355         local t=$(ls $DIR/$tdir | wc -l)
1356         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1357         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1358
1359         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1360                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1361 }
1362 run_test 24A "readdir() returns correct number of entries."
1363
1364 test_24B() { # LU-4805
1365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1366
1367         local count
1368
1369         test_mkdir $DIR/$tdir
1370         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1371                 error "create striped dir failed"
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 2 ] || error "Expected 2, got $count"
1375
1376         touch $DIR/$tdir/striped_dir/a
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 3 ] || error "Expected 3, got $count"
1380
1381         touch $DIR/$tdir/striped_dir/.f
1382
1383         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1384         [ $count -eq 4 ] || error "Expected 4, got $count"
1385
1386         rm -rf $DIR/$tdir || error "Can not delete directories"
1387 }
1388 run_test 24B "readdir for striped dir return correct number of entries"
1389
1390 test_24C() {
1391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1392
1393         mkdir $DIR/$tdir
1394         mkdir $DIR/$tdir/d0
1395         mkdir $DIR/$tdir/d1
1396
1397         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1398                 error "create striped dir failed"
1399
1400         cd $DIR/$tdir/d0/striped_dir
1401
1402         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1403         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1404         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d0_ino" = "$parent_ino" ] ||
1407                 error ".. wrong, expect $d0_ino, get $parent_ino"
1408
1409         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1410                 error "mv striped dir failed"
1411
1412         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1413
1414         [ "$d1_ino" = "$parent_ino" ] ||
1415                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1416 }
1417 run_test 24C "check .. in striped dir"
1418
1419 test_24E() {
1420         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1422
1423         mkdir -p $DIR/$tdir
1424         mkdir $DIR/$tdir/src_dir
1425         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1426                 error "create remote source failed"
1427
1428         touch $DIR/$tdir/src_dir/src_child/a
1429
1430         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1431                 error "create remote target dir failed"
1432
1433         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "create remote target child failed"
1435
1436         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1437                 error "rename dir cross MDT failed!"
1438
1439         find $DIR/$tdir
1440
1441         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1442                 error "src_child still exists after rename"
1443
1444         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1445                 error "missing file(a) after rename"
1446
1447         rm -rf $DIR/$tdir || error "Can not delete directories"
1448 }
1449 run_test 24E "cross MDT rename/link"
1450
1451 test_24F () {
1452         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1453
1454         local repeats=1000
1455         [ "$SLOW" = "no" ] && repeats=100
1456
1457         mkdir -p $DIR/$tdir
1458
1459         echo "$repeats repeats"
1460         for ((i = 0; i < repeats; i++)); do
1461                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1462                 touch $DIR/$tdir/test/a || error "touch fails"
1463                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1464                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1465         done
1466
1467         true
1468 }
1469 run_test 24F "hash order vs readdir (LU-11330)"
1470
1471 test_24G () {
1472         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1473
1474         local ino1
1475         local ino2
1476
1477         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1478         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1479         touch $DIR/$tdir-0/f1 || error "touch f1"
1480         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1481         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1482         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1483         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1484         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1485 }
1486 run_test 24G "migrate symlink in rename"
1487
1488 test_24H() {
1489         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1490         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1491                 skip "MDT1 should be on another node"
1492
1493         test_mkdir -i 1 -c 1 $DIR/$tdir
1494 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1495         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1496         touch $DIR/$tdir/$tfile || error "touch failed"
1497 }
1498 run_test 24H "repeat FLD_QUERY rpc"
1499
1500 test_25a() {
1501         echo '== symlink sanity ============================================='
1502
1503         test_mkdir $DIR/d25
1504         ln -s d25 $DIR/s25
1505         touch $DIR/s25/foo ||
1506                 error "File creation in symlinked directory failed"
1507 }
1508 run_test 25a "create file in symlinked directory ==============="
1509
1510 test_25b() {
1511         [ ! -d $DIR/d25 ] && test_25a
1512         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1513 }
1514 run_test 25b "lookup file in symlinked directory ==============="
1515
1516 test_26a() {
1517         test_mkdir $DIR/d26
1518         test_mkdir $DIR/d26/d26-2
1519         ln -s d26/d26-2 $DIR/s26
1520         touch $DIR/s26/foo || error "File creation failed"
1521 }
1522 run_test 26a "multiple component symlink ======================="
1523
1524 test_26b() {
1525         test_mkdir -p $DIR/$tdir/d26-2
1526         ln -s $tdir/d26-2/foo $DIR/s26-2
1527         touch $DIR/s26-2 || error "File creation failed"
1528 }
1529 run_test 26b "multiple component symlink at end of lookup ======"
1530
1531 test_26c() {
1532         test_mkdir $DIR/d26.2
1533         touch $DIR/d26.2/foo
1534         ln -s d26.2 $DIR/s26.2-1
1535         ln -s s26.2-1 $DIR/s26.2-2
1536         ln -s s26.2-2 $DIR/s26.2-3
1537         chmod 0666 $DIR/s26.2-3/foo
1538 }
1539 run_test 26c "chain of symlinks"
1540
1541 # recursive symlinks (bug 439)
1542 test_26d() {
1543         ln -s d26-3/foo $DIR/d26-3
1544 }
1545 run_test 26d "create multiple component recursive symlink"
1546
1547 test_26e() {
1548         [ ! -h $DIR/d26-3 ] && test_26d
1549         rm $DIR/d26-3
1550 }
1551 run_test 26e "unlink multiple component recursive symlink"
1552
1553 # recursive symlinks (bug 7022)
1554 test_26f() {
1555         test_mkdir $DIR/$tdir
1556         test_mkdir $DIR/$tdir/$tfile
1557         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1558         test_mkdir -p lndir/bar1
1559         test_mkdir $DIR/$tdir/$tfile/$tfile
1560         cd $tfile                || error "cd $tfile failed"
1561         ln -s .. dotdot          || error "ln dotdot failed"
1562         ln -s dotdot/lndir lndir || error "ln lndir failed"
1563         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1564         output=`ls $tfile/$tfile/lndir/bar1`
1565         [ "$output" = bar1 ] && error "unexpected output"
1566         rm -r $tfile             || error "rm $tfile failed"
1567         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1568 }
1569 run_test 26f "rm -r of a directory which has recursive symlink"
1570
1571 test_27a() {
1572         test_mkdir $DIR/$tdir
1573         $LFS getstripe $DIR/$tdir
1574         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1575         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1576         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1577 }
1578 run_test 27a "one stripe file"
1579
1580 test_27b() {
1581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1582
1583         test_mkdir $DIR/$tdir
1584         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1585         $LFS getstripe -c $DIR/$tdir/$tfile
1586         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1587                 error "two-stripe file doesn't have two stripes"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1590 }
1591 run_test 27b "create and write to two stripe file"
1592
1593 # 27c family tests specific striping, setstripe -o
1594 test_27ca() {
1595         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1596         test_mkdir -p $DIR/$tdir
1597         local osts="1"
1598
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1600         $LFS getstripe -i $DIR/$tdir/$tfile
1601         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1602                 error "stripe not on specified OST"
1603
1604         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1605 }
1606 run_test 27ca "one stripe on specified OST"
1607
1608 test_27cb() {
1609         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1610         test_mkdir -p $DIR/$tdir
1611         local osts="1,0"
1612         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1613         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1614         echo "$getstripe"
1615
1616         # Strip getstripe output to a space separated list of OSTs
1617         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1618                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1619         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1620                 error "stripes not on specified OSTs"
1621
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1623 }
1624 run_test 27cb "two stripes on specified OSTs"
1625
1626 test_27cc() {
1627         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1628         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1629                 skip "server does not support overstriping"
1630
1631         test_mkdir -p $DIR/$tdir
1632         local osts="0,0"
1633         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1634         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1635         echo "$getstripe"
1636
1637         # Strip getstripe output to a space separated list of OSTs
1638         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1639                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1640         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1641                 error "stripes not on specified OSTs"
1642
1643         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1644 }
1645 run_test 27cc "two stripes on the same OST"
1646
1647 test_27cd() {
1648         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1649         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1650                 skip "server does not support overstriping"
1651         test_mkdir -p $DIR/$tdir
1652         local osts="0,1,1,0"
1653         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1654         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1655         echo "$getstripe"
1656
1657         # Strip getstripe output to a space separated list of OSTs
1658         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1659                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1660         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1661                 error "stripes not on specified OSTs"
1662
1663         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1664 }
1665 run_test 27cd "four stripes on two OSTs"
1666
1667 test_27ce() {
1668         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1669                 skip_env "too many osts, skipping"
1670         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1671                 skip "server does not support overstriping"
1672         # We do one more stripe than we have OSTs
1673         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1674                 skip_env "ea_inode feature disabled"
1675
1676         test_mkdir -p $DIR/$tdir
1677         local osts=""
1678         for i in $(seq 0 $OSTCOUNT);
1679         do
1680                 osts=$osts"0"
1681                 if [ $i -ne $OSTCOUNT ]; then
1682                         osts=$osts","
1683                 fi
1684         done
1685         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1686         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1687         echo "$getstripe"
1688
1689         # Strip getstripe output to a space separated list of OSTs
1690         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1691                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1692         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1693                 error "stripes not on specified OSTs"
1694
1695         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1696 }
1697 run_test 27ce "more stripes than OSTs with -o"
1698
1699 test_27cf() {
1700         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1701         local pid=0
1702
1703         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1705         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1706         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1707                 error "failed to set $osp_proc=0"
1708
1709         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1710         pid=$!
1711         sleep 1
1712         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1713         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1714                 error "failed to set $osp_proc=1"
1715         wait $pid
1716         [[ $pid -ne 0 ]] ||
1717                 error "should return error due to $osp_proc=0"
1718 }
1719 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1720
1721 test_27cg() {
1722         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1723                 skip "server does not support overstriping"
1724         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1725         large_xattr_enabled || skip_env "ea_inode feature disabled"
1726
1727         local osts="0"
1728
1729         for ((i=1;i<1000;i++)); do
1730                 osts+=",$((i % OSTCOUNT))"
1731         done
1732
1733         local mdts=$(comma_list $(mdts_nodes))
1734         local before=$(do_nodes $mdts \
1735                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1736                 awk '/many credits/{print $3}' |
1737                 calc_sum)
1738
1739         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1740         $LFS getstripe $DIR/$tfile | grep stripe
1741
1742         rm -f $DIR/$tfile || error "can't unlink"
1743
1744         after=$(do_nodes $mdts \
1745                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1746                 awk '/many credits/{print $3}' |
1747                 calc_sum)
1748
1749         (( before == after )) ||
1750                 error "too many credits happened: $after > $before"
1751 }
1752 run_test 27cg "1000 shouldn't cause too many credits"
1753
1754 test_27d() {
1755         test_mkdir $DIR/$tdir
1756         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1757                 error "setstripe failed"
1758         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1759         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1760 }
1761 run_test 27d "create file with default settings"
1762
1763 test_27e() {
1764         # LU-5839 adds check for existed layout before setting it
1765         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1766                 skip "Need MDS version at least 2.7.56"
1767
1768         test_mkdir $DIR/$tdir
1769         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1770         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1771         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1772 }
1773 run_test 27e "setstripe existing file (should return error)"
1774
1775 test_27f() {
1776         test_mkdir $DIR/$tdir
1777         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1778                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1779         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1780                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1781         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1782         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1783 }
1784 run_test 27f "setstripe with bad stripe size (should return error)"
1785
1786 test_27g() {
1787         test_mkdir $DIR/$tdir
1788         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1789         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1790                 error "$DIR/$tdir/$tfile has object"
1791 }
1792 run_test 27g "$LFS getstripe with no objects"
1793
1794 test_27ga() {
1795         test_mkdir $DIR/$tdir
1796         touch $DIR/$tdir/$tfile || error "touch failed"
1797         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1798         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1799         local rc=$?
1800         (( rc == 2 )) || error "getstripe did not return ENOENT"
1801 }
1802 run_test 27ga "$LFS getstripe with missing file (should return error)"
1803
1804 test_27i() {
1805         test_mkdir $DIR/$tdir
1806         touch $DIR/$tdir/$tfile || error "touch failed"
1807         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1808                 error "missing objects"
1809 }
1810 run_test 27i "$LFS getstripe with some objects"
1811
1812 test_27j() {
1813         test_mkdir $DIR/$tdir
1814         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1815                 error "setstripe failed" || true
1816 }
1817 run_test 27j "setstripe with bad stripe offset (should return error)"
1818
1819 test_27k() { # bug 2844
1820         test_mkdir $DIR/$tdir
1821         local file=$DIR/$tdir/$tfile
1822         local ll_max_blksize=$((4 * 1024 * 1024))
1823         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1824         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1825         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1826         dd if=/dev/zero of=$file bs=4k count=1
1827         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1828         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1829 }
1830 run_test 27k "limit i_blksize for broken user apps"
1831
1832 test_27l() {
1833         mcreate $DIR/$tfile || error "creating file"
1834         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1835                 error "setstripe should have failed" || true
1836 }
1837 run_test 27l "check setstripe permissions (should return error)"
1838
1839 test_27m() {
1840         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1841
1842         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1843                 skip_env "multiple clients -- skipping"
1844
1845         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1846                    head -n1)
1847         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1848                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1849         fi
1850         stack_trap simple_cleanup_common
1851         test_mkdir $DIR/$tdir
1852         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1853         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1854                 error "dd should fill OST0"
1855         i=2
1856         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1857                 i=$((i + 1))
1858                 [ $i -gt 256 ] && break
1859         done
1860         i=$((i + 1))
1861         touch $DIR/$tdir/$tfile.$i
1862         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1863             awk '{print $1}'| grep -w "0") ] &&
1864                 error "OST0 was full but new created file still use it"
1865         i=$((i + 1))
1866         touch $DIR/$tdir/$tfile.$i
1867         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1868             awk '{print $1}'| grep -w "0") ] &&
1869                 error "OST0 was full but new created file still use it" || true
1870 }
1871 run_test 27m "create file while OST0 was full"
1872
1873 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1874 # if the OST isn't full anymore.
1875 reset_enospc() {
1876         local ostidx=${1:-""}
1877         local delay
1878         local ready
1879         local get_prealloc
1880
1881         local list=$(comma_list $(osts_nodes))
1882         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1883
1884         do_nodes $list lctl set_param fail_loc=0
1885         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1886         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1887                 awk '{print $1 * 2;exit;}')
1888         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1889                         grep -v \"^0$\""
1890         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1891 }
1892
1893 test_27n() {
1894         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1896         remote_mds_nodsh && skip "remote MDS with nodsh"
1897         remote_ost_nodsh && skip "remote OST with nodsh"
1898
1899         reset_enospc
1900         rm -f $DIR/$tdir/$tfile
1901         exhaust_precreations 0 0x80000215
1902         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1903         touch $DIR/$tdir/$tfile || error "touch failed"
1904         $LFS getstripe $DIR/$tdir/$tfile
1905         reset_enospc
1906 }
1907 run_test 27n "create file with some full OSTs"
1908
1909 test_27o() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917         exhaust_all_precreations 0x215
1918
1919         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1920
1921         reset_enospc
1922         rm -rf $DIR/$tdir/*
1923 }
1924 run_test 27o "create file with all full OSTs (should error)"
1925
1926 function create_and_checktime() {
1927         local fname=$1
1928         local loops=$2
1929         local i
1930
1931         for ((i=0; i < $loops; i++)); do
1932                 local start=$SECONDS
1933                 multiop $fname-$i Oc
1934                 ((SECONDS-start < TIMEOUT)) ||
1935                         error "creation took " $((SECONDS-$start)) && return 1
1936         done
1937 }
1938
1939 test_27oo() {
1940         local mdts=$(comma_list $(mdts_nodes))
1941
1942         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1943                 skip "Need MDS version at least 2.13.57"
1944
1945         local f0=$DIR/${tfile}-0
1946         local f1=$DIR/${tfile}-1
1947
1948         wait_delete_completed
1949
1950         # refill precreated objects
1951         $LFS setstripe -i0 -c1 $f0
1952
1953         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1954         # force QoS allocation policy
1955         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1956         stack_trap "do_nodes $mdts $LCTL set_param \
1957                 lov.*.qos_threshold_rr=$saved" EXIT
1958         sleep_maxage
1959
1960         # one OST is unavailable, but still have few objects preallocated
1961         stop ost1
1962         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1963                 rm -rf $f1 $DIR/$tdir*" EXIT
1964
1965         for ((i=0; i < 7; i++)); do
1966                 mkdir $DIR/$tdir$i || error "can't create dir"
1967                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1968                         error "can't set striping"
1969         done
1970         for ((i=0; i < 7; i++)); do
1971                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1972         done
1973         wait
1974 }
1975 run_test 27oo "don't let few threads to reserve too many objects"
1976
1977 test_27p() {
1978         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1980         remote_mds_nodsh && skip "remote MDS with nodsh"
1981         remote_ost_nodsh && skip "remote OST with nodsh"
1982
1983         reset_enospc
1984         rm -f $DIR/$tdir/$tfile
1985         test_mkdir $DIR/$tdir
1986
1987         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1988         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1989         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1990
1991         exhaust_precreations 0 0x80000215
1992         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1993         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1994         $LFS getstripe $DIR/$tdir/$tfile
1995
1996         reset_enospc
1997 }
1998 run_test 27p "append to a truncated file with some full OSTs"
1999
2000 test_27q() {
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003         remote_mds_nodsh && skip "remote MDS with nodsh"
2004         remote_ost_nodsh && skip "remote OST with nodsh"
2005
2006         reset_enospc
2007         rm -f $DIR/$tdir/$tfile
2008
2009         mkdir_on_mdt0 $DIR/$tdir
2010         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2011         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2012                 error "truncate $DIR/$tdir/$tfile failed"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2014
2015         exhaust_all_precreations 0x215
2016
2017         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2018         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2019
2020         reset_enospc
2021 }
2022 run_test 27q "append to truncated file with all OSTs full (should error)"
2023
2024 test_27r() {
2025         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028         remote_ost_nodsh && skip "remote OST with nodsh"
2029
2030         reset_enospc
2031         rm -f $DIR/$tdir/$tfile
2032         exhaust_precreations 0 0x80000215
2033
2034         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2035
2036         reset_enospc
2037 }
2038 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2039
2040 test_27s() { # bug 10725
2041         test_mkdir $DIR/$tdir
2042         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2043         local stripe_count=0
2044         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2045         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2046                 error "stripe width >= 2^32 succeeded" || true
2047
2048 }
2049 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2050
2051 test_27t() { # bug 10864
2052         WDIR=$(pwd)
2053         WLFS=$(which lfs)
2054         cd $DIR
2055         touch $tfile
2056         $WLFS getstripe $tfile
2057         cd $WDIR
2058 }
2059 run_test 27t "check that utils parse path correctly"
2060
2061 test_27u() { # bug 4900
2062         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2063         remote_mds_nodsh && skip "remote MDS with nodsh"
2064
2065         local index
2066         local list=$(comma_list $(mdts_nodes))
2067
2068 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2069         do_nodes $list $LCTL set_param fail_loc=0x139
2070         test_mkdir -p $DIR/$tdir
2071         stack_trap "simple_cleanup_common 1000"
2072         createmany -o $DIR/$tdir/$tfile 1000
2073         do_nodes $list $LCTL set_param fail_loc=0
2074
2075         TLOG=$TMP/$tfile.getstripe
2076         $LFS getstripe $DIR/$tdir > $TLOG
2077         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2078         [[ $OBJS -gt 0 ]] &&
2079                 error "$OBJS objects created on OST-0. See $TLOG" ||
2080                 rm -f $TLOG
2081 }
2082 run_test 27u "skip object creation on OSC w/o objects"
2083
2084 test_27v() { # bug 4900
2085         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2087         remote_mds_nodsh && skip "remote MDS with nodsh"
2088         remote_ost_nodsh && skip "remote OST with nodsh"
2089
2090         exhaust_all_precreations 0x215
2091         reset_enospc
2092
2093         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2094
2095         touch $DIR/$tdir/$tfile
2096         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2097         # all except ost1
2098         for (( i=1; i < OSTCOUNT; i++ )); do
2099                 do_facet ost$i lctl set_param fail_loc=0x705
2100         done
2101         local START=`date +%s`
2102         createmany -o $DIR/$tdir/$tfile 32
2103
2104         local FINISH=`date +%s`
2105         local TIMEOUT=`lctl get_param -n timeout`
2106         local PROCESS=$((FINISH - START))
2107         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2108                error "$FINISH - $START >= $TIMEOUT / 2"
2109         sleep $((TIMEOUT / 2 - PROCESS))
2110         reset_enospc
2111 }
2112 run_test 27v "skip object creation on slow OST"
2113
2114 test_27w() { # bug 10997
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2117         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2118                 error "stripe size $size != 65536" || true
2119         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2120                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2121 }
2122 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2123
2124 test_27wa() {
2125         [[ $OSTCOUNT -lt 2 ]] &&
2126                 skip_env "skipping multiple stripe count/offset test"
2127
2128         test_mkdir $DIR/$tdir
2129         for i in $(seq 1 $OSTCOUNT); do
2130                 offset=$((i - 1))
2131                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2132                         error "setstripe -c $i -i $offset failed"
2133                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2134                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2135                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2136                 [ $index -ne $offset ] &&
2137                         error "stripe offset $index != $offset" || true
2138         done
2139 }
2140 run_test 27wa "check $LFS setstripe -c -i options"
2141
2142 test_27x() {
2143         remote_ost_nodsh && skip "remote OST with nodsh"
2144         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2146
2147         OFFSET=$(($OSTCOUNT - 1))
2148         OSTIDX=0
2149         local OST=$(ostname_from_index $OSTIDX)
2150
2151         test_mkdir $DIR/$tdir
2152         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2153         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2154         sleep_maxage
2155         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2156         for i in $(seq 0 $OFFSET); do
2157                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2158                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2159                 error "OST0 was degraded but new created file still use it"
2160         done
2161         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2162 }
2163 run_test 27x "create files while OST0 is degraded"
2164
2165 test_27y() {
2166         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2167         remote_mds_nodsh && skip "remote MDS with nodsh"
2168         remote_ost_nodsh && skip "remote OST with nodsh"
2169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2170
2171         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2172         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2173                 osp.$mdtosc.prealloc_last_id)
2174         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2175                 osp.$mdtosc.prealloc_next_id)
2176         local fcount=$((last_id - next_id))
2177         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2178         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2179
2180         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2181                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2182         local OST_DEACTIVE_IDX=-1
2183         local OSC
2184         local OSTIDX
2185         local OST
2186
2187         for OSC in $MDS_OSCS; do
2188                 OST=$(osc_to_ost $OSC)
2189                 OSTIDX=$(index_from_ostuuid $OST)
2190                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2191                         OST_DEACTIVE_IDX=$OSTIDX
2192                 fi
2193                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2194                         echo $OSC "is Deactivated:"
2195                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2196                 fi
2197         done
2198
2199         OSTIDX=$(index_from_ostuuid $OST)
2200         test_mkdir $DIR/$tdir
2201         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=1
2210                 fi
2211         done
2212
2213         sleep_maxage
2214         createmany -o $DIR/$tdir/$tfile $fcount
2215
2216         for OSC in $MDS_OSCS; do
2217                 OST=$(osc_to_ost $OSC)
2218                 OSTIDX=$(index_from_ostuuid $OST)
2219                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2220                         echo $OST "is recovered from degraded:"
2221                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2222                                                 obdfilter.$OST.degraded=0
2223                 else
2224                         do_facet $SINGLEMDS lctl --device %$OSC activate
2225                 fi
2226         done
2227
2228         # all osp devices get activated, hence -1 stripe count restored
2229         local stripe_count=0
2230
2231         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2232         # devices get activated.
2233         sleep_maxage
2234         $LFS setstripe -c -1 $DIR/$tfile
2235         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2236         rm -f $DIR/$tfile
2237         [ $stripe_count -ne $OSTCOUNT ] &&
2238                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2239         return 0
2240 }
2241 run_test 27y "create files while OST0 is degraded and the rest inactive"
2242
2243 check_seq_oid()
2244 {
2245         log "check file $1"
2246
2247         lmm_count=$($LFS getstripe -c $1)
2248         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2249         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2250
2251         local old_ifs="$IFS"
2252         IFS=$'[:]'
2253         fid=($($LFS path2fid $1))
2254         IFS="$old_ifs"
2255
2256         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2257         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2258
2259         # compare lmm_seq and lu_fid->f_seq
2260         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2261         # compare lmm_object_id and lu_fid->oid
2262         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2263
2264         # check the trusted.fid attribute of the OST objects of the file
2265         local have_obdidx=false
2266         local stripe_nr=0
2267         $LFS getstripe $1 | while read obdidx oid hex seq; do
2268                 # skip lines up to and including "obdidx"
2269                 [ -z "$obdidx" ] && break
2270                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2271                 $have_obdidx || continue
2272
2273                 local ost=$((obdidx + 1))
2274                 local dev=$(ostdevname $ost)
2275                 local oid_hex
2276
2277                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2278
2279                 seq=$(echo $seq | sed -e "s/^0x//g")
2280                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2281                         oid_hex=$(echo $oid)
2282                 else
2283                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2284                 fi
2285                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2286
2287                 local ff=""
2288                 #
2289                 # Don't unmount/remount the OSTs if we don't need to do that.
2290                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2291                 # update too, until that use mount/ll_decode_filter_fid/mount.
2292                 # Re-enable when debugfs will understand new filter_fid.
2293                 #
2294                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2295                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2296                                 $dev 2>/dev/null" | grep "parent=")
2297                 fi
2298                 if [ -z "$ff" ]; then
2299                         stop ost$ost
2300                         mount_fstype ost$ost
2301                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2302                                 $(facet_mntpt ost$ost)/$obj_file)
2303                         unmount_fstype ost$ost
2304                         start ost$ost $dev $OST_MOUNT_OPTS
2305                         clients_up
2306                 fi
2307
2308                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2309
2310                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2311
2312                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2313                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2314                 #
2315                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2316                 #       stripe_size=1048576 component_id=1 component_start=0 \
2317                 #       component_end=33554432
2318                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2319                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2320                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2321                 local ff_pstripe
2322                 if grep -q 'stripe=' <<<$ff; then
2323                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2324                 else
2325                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2326                         # into f_ver in this case.  See comment on ff_parent.
2327                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2328                 fi
2329
2330                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2331                 [ $ff_pseq = $lmm_seq ] ||
2332                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2333                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2334                 [ $ff_poid = $lmm_oid ] ||
2335                         error "FF parent OID $ff_poid != $lmm_oid"
2336                 (($ff_pstripe == $stripe_nr)) ||
2337                         error "FF stripe $ff_pstripe != $stripe_nr"
2338
2339                 stripe_nr=$((stripe_nr + 1))
2340                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2341                         continue
2342                 if grep -q 'stripe_count=' <<<$ff; then
2343                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2344                                             -e 's/ .*//' <<<$ff)
2345                         [ $lmm_count = $ff_scnt ] ||
2346                                 error "FF stripe count $lmm_count != $ff_scnt"
2347                 fi
2348         done
2349 }
2350
2351 test_27z() {
2352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2353         remote_ost_nodsh && skip "remote OST with nodsh"
2354
2355         test_mkdir $DIR/$tdir
2356         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2357                 { error "setstripe -c -1 failed"; return 1; }
2358         # We need to send a write to every object to get parent FID info set.
2359         # This _should_ also work for setattr, but does not currently.
2360         # touch $DIR/$tdir/$tfile-1 ||
2361         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2362                 { error "dd $tfile-1 failed"; return 2; }
2363         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2364                 { error "setstripe -c -1 failed"; return 3; }
2365         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2366                 { error "dd $tfile-2 failed"; return 4; }
2367
2368         # make sure write RPCs have been sent to OSTs
2369         sync; sleep 5; sync
2370
2371         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2372         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2373 }
2374 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2375
2376 test_27A() { # b=19102
2377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2378
2379         save_layout_restore_at_exit $MOUNT
2380         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2381         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2382                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2383         local default_size=$($LFS getstripe -S $MOUNT)
2384         local default_offset=$($LFS getstripe -i $MOUNT)
2385         local dsize=$(do_facet $SINGLEMDS \
2386                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2387         [ $default_size -eq $dsize ] ||
2388                 error "stripe size $default_size != $dsize"
2389         [ $default_offset -eq -1 ] ||
2390                 error "stripe offset $default_offset != -1"
2391 }
2392 run_test 27A "check filesystem-wide default LOV EA values"
2393
2394 test_27B() { # LU-2523
2395         test_mkdir $DIR/$tdir
2396         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2397         touch $DIR/$tdir/f0
2398         # open f1 with O_LOV_DELAY_CREATE
2399         # rename f0 onto f1
2400         # call setstripe ioctl on open file descriptor for f1
2401         # close
2402         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2403                 $DIR/$tdir/f0
2404
2405         rm -f $DIR/$tdir/f1
2406         # open f1 with O_LOV_DELAY_CREATE
2407         # unlink f1
2408         # call setstripe ioctl on open file descriptor for f1
2409         # close
2410         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2411
2412         # Allow multiop to fail in imitation of NFS's busted semantics.
2413         true
2414 }
2415 run_test 27B "call setstripe on open unlinked file/rename victim"
2416
2417 # 27C family tests full striping and overstriping
2418 test_27Ca() { #LU-2871
2419         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2420
2421         declare -a ost_idx
2422         local index
2423         local found
2424         local i
2425         local j
2426
2427         test_mkdir $DIR/$tdir
2428         cd $DIR/$tdir
2429         for i in $(seq 0 $((OSTCOUNT - 1))); do
2430                 # set stripe across all OSTs starting from OST$i
2431                 $LFS setstripe -i $i -c -1 $tfile$i
2432                 # get striping information
2433                 ost_idx=($($LFS getstripe $tfile$i |
2434                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2435                 echo "OST Index: ${ost_idx[*]}"
2436
2437                 # check the layout
2438                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2439                         error "${#ost_idx[@]} != $OSTCOUNT"
2440
2441                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2442                         found=0
2443                         for j in "${ost_idx[@]}"; do
2444                                 if [ $index -eq $j ]; then
2445                                         found=1
2446                                         break
2447                                 fi
2448                         done
2449                         [ $found = 1 ] ||
2450                                 error "Can not find $index in ${ost_idx[*]}"
2451                 done
2452         done
2453 }
2454 run_test 27Ca "check full striping across all OSTs"
2455
2456 test_27Cb() {
2457         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2458                 skip "server does not support overstriping"
2459         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2460                 skip_env "too many osts, skipping"
2461
2462         test_mkdir -p $DIR/$tdir
2463         local setcount=$(($OSTCOUNT * 2))
2464         [ $setcount -lt 160 ] || large_xattr_enabled ||
2465                 skip_env "ea_inode feature disabled"
2466
2467         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2468                 error "setstripe failed"
2469
2470         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2471         [ $count -eq $setcount ] ||
2472                 error "stripe count $count, should be $setcount"
2473
2474         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2475                 error "overstriped should be set in pattern"
2476
2477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2478                 error "dd failed"
2479 }
2480 run_test 27Cb "more stripes than OSTs with -C"
2481
2482 test_27Cc() {
2483         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2484                 skip "server does not support overstriping"
2485         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2486
2487         test_mkdir -p $DIR/$tdir
2488         local setcount=$(($OSTCOUNT - 1))
2489
2490         [ $setcount -lt 160 ] || large_xattr_enabled ||
2491                 skip_env "ea_inode feature disabled"
2492
2493         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2494                 error "setstripe failed"
2495
2496         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2497         [ $count -eq $setcount ] ||
2498                 error "stripe count $count, should be $setcount"
2499
2500         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2501                 error "overstriped should not be set in pattern"
2502
2503         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2504                 error "dd failed"
2505 }
2506 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2507
2508 test_27Cd() {
2509         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2510                 skip "server does not support overstriping"
2511         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2512         large_xattr_enabled || skip_env "ea_inode feature disabled"
2513
2514         force_new_seq_all
2515
2516         test_mkdir -p $DIR/$tdir
2517         local setcount=$LOV_MAX_STRIPE_COUNT
2518
2519         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2520                 error "setstripe failed"
2521
2522         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2523         [ $count -eq $setcount ] ||
2524                 error "stripe count $count, should be $setcount"
2525
2526         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2527                 error "overstriped should be set in pattern"
2528
2529         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2530                 error "dd failed"
2531
2532         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2533 }
2534 run_test 27Cd "test maximum stripe count"
2535
2536 test_27Ce() {
2537         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2538                 skip "server does not support overstriping"
2539         test_mkdir -p $DIR/$tdir
2540
2541         pool_add $TESTNAME || error "Pool creation failed"
2542         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2543
2544         local setcount=8
2545
2546         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2547                 error "setstripe failed"
2548
2549         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2550         [ $count -eq $setcount ] ||
2551                 error "stripe count $count, should be $setcount"
2552
2553         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2554                 error "overstriped should be set in pattern"
2555
2556         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2557                 error "dd failed"
2558
2559         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2560 }
2561 run_test 27Ce "test pool with overstriping"
2562
2563 test_27Cf() {
2564         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2565                 skip "server does not support overstriping"
2566         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2567                 skip_env "too many osts, skipping"
2568
2569         test_mkdir -p $DIR/$tdir
2570
2571         local setcount=$(($OSTCOUNT * 2))
2572         [ $setcount -lt 160 ] || large_xattr_enabled ||
2573                 skip_env "ea_inode feature disabled"
2574
2575         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2576                 error "setstripe failed"
2577
2578         echo 1 > $DIR/$tdir/$tfile
2579
2580         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2581         [ $count -eq $setcount ] ||
2582                 error "stripe count $count, should be $setcount"
2583
2584         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2585                 error "overstriped should be set in pattern"
2586
2587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2588                 error "dd failed"
2589
2590         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2591 }
2592 run_test 27Cf "test default inheritance with overstriping"
2593
2594 test_27Cg() {
2595         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2596                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2597
2598         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2599         (( $? != 0 )) || error "must be an error for not existent OST#"
2600 }
2601 run_test 27Cg "test setstripe with wrong OST idx"
2602
2603 test_27D() {
2604         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2605         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2606         remote_mds_nodsh && skip "remote MDS with nodsh"
2607
2608         local POOL=${POOL:-testpool}
2609         local first_ost=0
2610         local last_ost=$(($OSTCOUNT - 1))
2611         local ost_step=1
2612         local ost_list=$(seq $first_ost $ost_step $last_ost)
2613         local ost_range="$first_ost $last_ost $ost_step"
2614
2615         test_mkdir $DIR/$tdir
2616         pool_add $POOL || error "pool_add failed"
2617         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2618
2619         local skip27D
2620         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2621                 skip27D+="-s 29"
2622         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2623                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2624                         skip27D+=" -s 30,31"
2625         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2626           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2627                 skip27D+=" -s 32,33"
2628         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2629                 skip27D+=" -s 34"
2630         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2631                 error "llapi_layout_test failed"
2632
2633         destroy_test_pools || error "destroy test pools failed"
2634 }
2635 run_test 27D "validate llapi_layout API"
2636
2637 # Verify that default_easize is increased from its initial value after
2638 # accessing a widely striped file.
2639 test_27E() {
2640         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2641         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2642                 skip "client does not have LU-3338 fix"
2643
2644         # 72 bytes is the minimum space required to store striping
2645         # information for a file striped across one OST:
2646         # (sizeof(struct lov_user_md_v3) +
2647         #  sizeof(struct lov_user_ost_data_v1))
2648         local min_easize=72
2649         $LCTL set_param -n llite.*.default_easize $min_easize ||
2650                 error "lctl set_param failed"
2651         local easize=$($LCTL get_param -n llite.*.default_easize)
2652
2653         [ $easize -eq $min_easize ] ||
2654                 error "failed to set default_easize"
2655
2656         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2657                 error "setstripe failed"
2658         # In order to ensure stat() call actually talks to MDS we need to
2659         # do something drastic to this file to shake off all lock, e.g.
2660         # rename it (kills lookup lock forcing cache cleaning)
2661         mv $DIR/$tfile $DIR/${tfile}-1
2662         ls -l $DIR/${tfile}-1
2663         rm $DIR/${tfile}-1
2664
2665         easize=$($LCTL get_param -n llite.*.default_easize)
2666
2667         [ $easize -gt $min_easize ] ||
2668                 error "default_easize not updated"
2669 }
2670 run_test 27E "check that default extended attribute size properly increases"
2671
2672 test_27F() { # LU-5346/LU-7975
2673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2674         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2675         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2676                 skip "Need MDS version at least 2.8.51"
2677         remote_ost_nodsh && skip "remote OST with nodsh"
2678
2679         test_mkdir $DIR/$tdir
2680         rm -f $DIR/$tdir/f0
2681         $LFS setstripe -c 2 $DIR/$tdir
2682
2683         # stop all OSTs to reproduce situation for LU-7975 ticket
2684         for num in $(seq $OSTCOUNT); do
2685                 stop ost$num
2686         done
2687
2688         # open/create f0 with O_LOV_DELAY_CREATE
2689         # truncate f0 to a non-0 size
2690         # close
2691         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2692
2693         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2694         # open/write it again to force delayed layout creation
2695         cat /etc/hosts > $DIR/$tdir/f0 &
2696         catpid=$!
2697
2698         # restart OSTs
2699         for num in $(seq $OSTCOUNT); do
2700                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2701                         error "ost$num failed to start"
2702         done
2703
2704         wait $catpid || error "cat failed"
2705
2706         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2707         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2708                 error "wrong stripecount"
2709
2710 }
2711 run_test 27F "Client resend delayed layout creation with non-zero size"
2712
2713 test_27G() { #LU-10629
2714         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2715                 skip "Need MDS version at least 2.11.51"
2716         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2717         remote_mds_nodsh && skip "remote MDS with nodsh"
2718         local POOL=${POOL:-testpool}
2719         local ostrange="0 0 1"
2720
2721         test_mkdir $DIR/$tdir
2722         touch $DIR/$tdir/$tfile.nopool
2723         pool_add $POOL || error "pool_add failed"
2724         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2725         $LFS setstripe -p $POOL $DIR/$tdir
2726
2727         local pool=$($LFS getstripe -p $DIR/$tdir)
2728
2729         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2730         touch $DIR/$tdir/$tfile.default
2731         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2732         $LFS find $DIR/$tdir -type f --pool $POOL
2733         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2734         [[ "$found" == "2" ]] ||
2735                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2736
2737         $LFS setstripe -d $DIR/$tdir
2738
2739         pool=$($LFS getstripe -p -d $DIR/$tdir)
2740
2741         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2742 }
2743 run_test 27G "Clear OST pool from stripe"
2744
2745 test_27H() {
2746         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2747                 skip "Need MDS version newer than 2.11.54"
2748         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2749         test_mkdir $DIR/$tdir
2750         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2751         touch $DIR/$tdir/$tfile
2752         $LFS getstripe -c $DIR/$tdir/$tfile
2753         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2754                 error "two-stripe file doesn't have two stripes"
2755
2756         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2757         $LFS getstripe -y $DIR/$tdir/$tfile
2758         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2759              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2760                 error "expected l_ost_idx: [02]$ not matched"
2761
2762         # make sure ost list has been cleared
2763         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2764         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2765                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2766         touch $DIR/$tdir/f3
2767         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2768 }
2769 run_test 27H "Set specific OSTs stripe"
2770
2771 test_27I() {
2772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2774         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2775                 skip "Need MDS version newer than 2.12.52"
2776         local pool=$TESTNAME
2777         local ostrange="1 1 1"
2778
2779         save_layout_restore_at_exit $MOUNT
2780         $LFS setstripe -c 2 -i 0 $MOUNT
2781         pool_add $pool || error "pool_add failed"
2782         pool_add_targets $pool $ostrange ||
2783                 error "pool_add_targets failed"
2784         test_mkdir $DIR/$tdir
2785         $LFS setstripe -p $pool $DIR/$tdir
2786         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2787         $LFS getstripe $DIR/$tdir/$tfile
2788 }
2789 run_test 27I "check that root dir striping does not break parent dir one"
2790
2791 test_27J() {
2792         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2793                 skip "Need MDS version newer than 2.12.51"
2794
2795         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2796         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2797         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2798            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2799                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2800
2801         test_mkdir $DIR/$tdir
2802         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2803         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2804
2805         # create foreign file (raw way)
2806         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2807                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2808
2809         ! $LFS setstripe --foreign --flags foo \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile with '--flags foo' should fail"
2812
2813         ! $LFS setstripe --foreign --flags 0xffffffff \
2814                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2815                         error "creating $tfile w/ 0xffffffff flags should fail"
2816
2817         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2818                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2819
2820         # verify foreign file (raw way)
2821         parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2823                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2824         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2825                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2826         parse_foreign_file -f $DIR/$tdir/$tfile |
2827                 grep "lov_foreign_size: 73" ||
2828                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2829         parse_foreign_file -f $DIR/$tdir/$tfile |
2830                 grep "lov_foreign_type: 1" ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2832         parse_foreign_file -f $DIR/$tdir/$tfile |
2833                 grep "lov_foreign_flags: 0x0000DA08" ||
2834                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2835         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2836                 grep "lov_foreign_value: 0x" |
2837                 sed -e 's/lov_foreign_value: 0x//')
2838         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2839         [[ $lov = ${lov2// /} ]] ||
2840                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2841
2842         # create foreign file (lfs + API)
2843         $LFS setstripe --foreign=none --flags 0xda08 \
2844                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2845                 error "$DIR/$tdir/${tfile}2: create failed"
2846
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2848                 grep "lfm_magic:.*0x0BD70BD0" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2850         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2852                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2853         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2854                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2855         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2856                 grep "lfm_flags:.*0x0000DA08" ||
2857                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2858         $LFS getstripe $DIR/$tdir/${tfile}2 |
2859                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2860                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2861
2862         # modify striping should fail
2863         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2864                 error "$DIR/$tdir/$tfile: setstripe should fail"
2865         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2867
2868         # R/W should fail
2869         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2870         cat $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: read should fail"
2872         cat /etc/passwd > $DIR/$tdir/$tfile &&
2873                 error "$DIR/$tdir/$tfile: write should fail"
2874         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2875                 error "$DIR/$tdir/${tfile}2: write should fail"
2876
2877         # chmod should work
2878         chmod 222 $DIR/$tdir/$tfile ||
2879                 error "$DIR/$tdir/$tfile: chmod failed"
2880         chmod 222 $DIR/$tdir/${tfile}2 ||
2881                 error "$DIR/$tdir/${tfile}2: chmod failed"
2882
2883         # chown should work
2884         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2885                 error "$DIR/$tdir/$tfile: chown failed"
2886         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2887                 error "$DIR/$tdir/${tfile}2: chown failed"
2888
2889         # rename should work
2890         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2891                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2892         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2893                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2894
2895         #remove foreign file
2896         rm $DIR/$tdir/${tfile}.new ||
2897                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2898         rm $DIR/$tdir/${tfile}2.new ||
2899                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2900 }
2901 run_test 27J "basic ops on file with foreign LOV"
2902
2903 test_27K() {
2904         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2905                 skip "Need MDS version newer than 2.12.49"
2906
2907         test_mkdir $DIR/$tdir
2908         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2909         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2910
2911         # create foreign dir (raw way)
2912         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2913                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags foo \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir with '--flags foo' should fail"
2918
2919         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2920                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2921                         error "creating $tdir w/ 0xffffffff flags should fail"
2922
2923         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2924                 error "create_foreign_dir FAILED"
2925
2926         # verify foreign dir (raw way)
2927         parse_foreign_dir -d $DIR/$tdir/$tdir |
2928                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2929                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2931                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2932         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2933                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2934         parse_foreign_dir -d $DIR/$tdir/$tdir |
2935                 grep "lmv_foreign_flags: 55813$" ||
2936                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2937         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2938                 grep "lmv_foreign_value: 0x" |
2939                 sed 's/lmv_foreign_value: 0x//')
2940         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2941                 sed 's/ //g')
2942         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2943
2944         # create foreign dir (lfs + API)
2945         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2946                 $DIR/$tdir/${tdir}2 ||
2947                 error "$DIR/$tdir/${tdir}2: create failed"
2948
2949         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2950
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2952                 grep "lfm_magic:.*0x0CD50CD0" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2954         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2955         # - sizeof(lfm_type) - sizeof(lfm_flags)
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2957                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2958         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2959                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2960         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2961                 grep "lfm_flags:.*0x0000DA05" ||
2962                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2963         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2964                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2965                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2966
2967         # file create in dir should fail
2968         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2969         touch $DIR/$tdir/${tdir}2/$tfile &&
2970                 error "$DIR/${tdir}2: file create should fail"
2971
2972         # chmod should work
2973         chmod 777 $DIR/$tdir/$tdir ||
2974                 error "$DIR/$tdir: chmod failed"
2975         chmod 777 $DIR/$tdir/${tdir}2 ||
2976                 error "$DIR/${tdir}2: chmod failed"
2977
2978         # chown should work
2979         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2980                 error "$DIR/$tdir: chown failed"
2981         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2982                 error "$DIR/${tdir}2: chown failed"
2983
2984         # rename should work
2985         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2986                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2987         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2988                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2989
2990         #remove foreign dir
2991         rmdir $DIR/$tdir/${tdir}.new ||
2992                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2993         rmdir $DIR/$tdir/${tdir}2.new ||
2994                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2995 }
2996 run_test 27K "basic ops on dir with foreign LMV"
2997
2998 test_27L() {
2999         remote_mds_nodsh && skip "remote MDS with nodsh"
3000
3001         local POOL=${POOL:-$TESTNAME}
3002
3003         pool_add $POOL || error "pool_add failed"
3004
3005         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3006                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3007                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3008 }
3009 run_test 27L "lfs pool_list gives correct pool name"
3010
3011 test_27M() {
3012         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3013                 skip "Need MDS version >= than 2.12.57"
3014         remote_mds_nodsh && skip "remote MDS with nodsh"
3015         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3016
3017         # Set default striping on directory
3018         local setcount=4
3019         local stripe_opt
3020         local mdts=$(comma_list $(mdts_nodes))
3021
3022         # if we run against a 2.12 server which lacks overstring support
3023         # then the connect_flag will not report overstriping, even if client
3024         # is 2.14+
3025         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3026                 stripe_opt="-C $setcount"
3027         elif (( $OSTCOUNT >= $setcount )); then
3028                 stripe_opt="-c $setcount"
3029         else
3030                 skip "server does not support overstriping"
3031         fi
3032
3033         test_mkdir $DIR/$tdir
3034
3035         # Validate existing append_* params and ensure restore
3036         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3037         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3039
3040         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3041         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3042         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3043
3044         $LFS setstripe $stripe_opt $DIR/$tdir
3045
3046         echo 1 > $DIR/$tdir/${tfile}.1
3047         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3048         (( $count == $setcount )) ||
3049                 error "(1) stripe count $count, should be $setcount"
3050
3051         local appendcount=$orig_count
3052         echo 1 >> $DIR/$tdir/${tfile}.2_append
3053         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3054         (( $count == $appendcount )) ||
3055                 error "(2)stripe count $count, should be $appendcount for append"
3056
3057         # Disable O_APPEND striping, verify it works
3058         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3059
3060         # Should now get the default striping, which is 4
3061         setcount=4
3062         echo 1 >> $DIR/$tdir/${tfile}.3_append
3063         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3064         (( $count == $setcount )) ||
3065                 error "(3) stripe count $count, should be $setcount"
3066
3067         # Try changing the stripe count for append files
3068         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3069
3070         # Append striping is now 2 (directory default is still 4)
3071         appendcount=2
3072         echo 1 >> $DIR/$tdir/${tfile}.4_append
3073         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3074         (( $count == $appendcount )) ||
3075                 error "(4) stripe count $count, should be $appendcount for append"
3076
3077         # Test append stripe count of -1
3078         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3079         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3080                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3081                 touch $DIR/$tdir/$tfile.specific.{1..128}
3082         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3083
3084         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3085         appendcount=$OSTCOUNT
3086         echo 1 >> $DIR/$tdir/${tfile}.5
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3088         (( $count == $appendcount )) ||
3089                 error "(5) stripe count $count, should be $appendcount for append"
3090
3091         # Set append striping back to default of 1
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3093
3094         # Try a new default striping, PFL + DOM
3095         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3096
3097         # Create normal DOM file, DOM returns stripe count == 0
3098         setcount=0
3099         touch $DIR/$tdir/${tfile}.6
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3101         (( $count == $setcount )) ||
3102                 error "(6) stripe count $count, should be $setcount"
3103
3104         # Show
3105         appendcount=1
3106         echo 1 >> $DIR/$tdir/${tfile}.7_append
3107         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3108         (( $count == $appendcount )) ||
3109                 error "(7) stripe count $count, should be $appendcount for append"
3110
3111         # Clean up DOM layout
3112         $LFS setstripe -d $DIR/$tdir
3113
3114         save_layout_restore_at_exit $MOUNT
3115         # Now test that append striping works when layout is from root
3116         $LFS setstripe -c 2 $MOUNT
3117         # Make a special directory for this
3118         mkdir $DIR/${tdir}/${tdir}.2
3119
3120         # Verify for normal file
3121         setcount=2
3122         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3123         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3124         (( $count == $setcount )) ||
3125                 error "(8) stripe count $count, should be $setcount"
3126
3127         appendcount=1
3128         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3129         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3130         (( $count == $appendcount )) ||
3131                 error "(9) stripe count $count, should be $appendcount for append"
3132
3133         # Now test O_APPEND striping with pools
3134         pool_add $TESTNAME || error "pool creation failed"
3135         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3136         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3137
3138         echo 1 >> $DIR/$tdir/${tfile}.10_append
3139
3140         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3141         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3142
3143         # Check that count is still correct
3144         appendcount=1
3145         echo 1 >> $DIR/$tdir/${tfile}.11_append
3146         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3147         (( $count == $appendcount )) ||
3148                 error "(11) stripe count $count, should be $appendcount for append"
3149
3150         # Disable O_APPEND stripe count, verify pool works separately
3151         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3152
3153         echo 1 >> $DIR/$tdir/${tfile}.12_append
3154
3155         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3156         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3157
3158         # Remove pool setting, verify it's not applied
3159         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3160
3161         echo 1 >> $DIR/$tdir/${tfile}.13_append
3162
3163         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3164         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3165 }
3166 run_test 27M "test O_APPEND striping"
3167
3168 test_27N() {
3169         combined_mgs_mds && skip "needs separate MGS/MDT"
3170
3171         pool_add $TESTNAME || error "pool_add failed"
3172         do_facet mgs "$LCTL pool_list $FSNAME" |
3173                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3174                 error "lctl pool_list on MGS failed"
3175 }
3176 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3177
3178 clean_foreign_symlink() {
3179         trap 0
3180         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3181         for i in $DIR/$tdir/* ; do
3182                 $LFS unlink_foreign $i || true
3183         done
3184 }
3185
3186 test_27O() {
3187         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3188                 skip "Need MDS version newer than 2.12.51"
3189
3190         test_mkdir $DIR/$tdir
3191         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3192         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3193
3194         trap clean_foreign_symlink EXIT
3195
3196         # enable foreign_symlink behaviour
3197         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3198
3199         # foreign symlink LOV format is a partial path by default
3200
3201         # create foreign file (lfs + API)
3202         $LFS setstripe --foreign=symlink --flags 0xda05 \
3203                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}: create failed"
3205
3206         $LFS getstripe -v $DIR/$tdir/${tfile} |
3207                 grep "lfm_magic:.*0x0BD70BD0" ||
3208                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3209         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3210                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3211         $LFS getstripe -v $DIR/$tdir/${tfile} |
3212                 grep "lfm_flags:.*0x0000DA05" ||
3213                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3214         $LFS getstripe $DIR/$tdir/${tfile} |
3215                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3216                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3217
3218         # modify striping should fail
3219         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3220                 error "$DIR/$tdir/$tfile: setstripe should fail"
3221
3222         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3223         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3224         cat /etc/passwd > $DIR/$tdir/$tfile &&
3225                 error "$DIR/$tdir/$tfile: write should fail"
3226
3227         # rename should succeed
3228         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3229                 error "$DIR/$tdir/$tfile: rename has failed"
3230
3231         #remove foreign_symlink file should fail
3232         rm $DIR/$tdir/${tfile}.new &&
3233                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3234
3235         #test fake symlink
3236         mkdir /tmp/${uuid1} ||
3237                 error "/tmp/${uuid1}: mkdir has failed"
3238         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3239                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3240         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3241         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3242                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3243         #read should succeed now
3244         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3245                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3246         #write should succeed now
3247         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3248                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3249         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3251         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3252                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3253
3254         #check that getstripe still works
3255         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3257
3258         # chmod should still succeed
3259         chmod 644 $DIR/$tdir/${tfile}.new ||
3260                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3261
3262         # chown should still succeed
3263         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3264                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3265
3266         # rename should still succeed
3267         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3268                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3269
3270         #remove foreign_symlink file should still fail
3271         rm $DIR/$tdir/${tfile} &&
3272                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3273
3274         #use special ioctl() to unlink foreign_symlink file
3275         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3276                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3277
3278 }
3279 run_test 27O "basic ops on foreign file of symlink type"
3280
3281 test_27P() {
3282         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3283                 skip "Need MDS version newer than 2.12.49"
3284
3285         test_mkdir $DIR/$tdir
3286         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3287         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3288
3289         trap clean_foreign_symlink EXIT
3290
3291         # enable foreign_symlink behaviour
3292         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3293
3294         # foreign symlink LMV format is a partial path by default
3295
3296         # create foreign dir (lfs + API)
3297         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3298                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3299                 error "$DIR/$tdir/${tdir}: create failed"
3300
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3302
3303         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3304                 grep "lfm_magic:.*0x0CD50CD0" ||
3305                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3306         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3307                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3308         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3309                 grep "lfm_flags:.*0x0000DA05" ||
3310                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3311         $LFS getdirstripe $DIR/$tdir/${tdir} |
3312                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3313                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3314
3315         # file create in dir should fail
3316         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3317         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3318
3319         # rename should succeed
3320         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3321                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3322
3323         #remove foreign_symlink dir should fail
3324         rmdir $DIR/$tdir/${tdir}.new &&
3325                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3326
3327         #test fake symlink
3328         mkdir -p /tmp/${uuid1}/${uuid2} ||
3329                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3330         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3331                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3332         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3333         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3334                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3335         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3336                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3337
3338         #check that getstripe fails now that foreign_symlink enabled
3339         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3341
3342         # file create in dir should work now
3343         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3344                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3345         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3346                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3347         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3348                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3349
3350         # chmod should still succeed
3351         chmod 755 $DIR/$tdir/${tdir}.new ||
3352                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3353
3354         # chown should still succeed
3355         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3356                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3357
3358         # rename should still succeed
3359         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3360                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3361
3362         #remove foreign_symlink dir should still fail
3363         rmdir $DIR/$tdir/${tdir} &&
3364                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3365
3366         #use special ioctl() to unlink foreign_symlink file
3367         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3368                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3369
3370         #created file should still exist
3371         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3372                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3373         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3374                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3375 }
3376 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3377
3378 test_27Q() {
3379         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3380         stack_trap "rm -f $TMP/$tfile*"
3381
3382         test_mkdir $DIR/$tdir-1
3383         test_mkdir $DIR/$tdir-2
3384
3385         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3386         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3387
3388         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3389         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3390
3391         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3392         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3393
3394         # Create some bad symlinks and ensure that we don't loop
3395         # forever or something. These should return ELOOP (40) and
3396         # ENOENT (2) but I don't want to test for that because there's
3397         # always some weirdo architecture that needs to ruin
3398         # everything by defining these error numbers differently.
3399
3400         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3401         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3402
3403         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3404         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3405
3406         return 0
3407 }
3408 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3409
3410 test_27R() {
3411         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3412                 skip "need MDS 2.14.55 or later"
3413         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3414
3415         local testdir="$DIR/$tdir"
3416         test_mkdir -p $testdir
3417         stack_trap "rm -rf $testdir"
3418         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3419
3420         local f1="$testdir/f1"
3421         touch $f1 || error "failed to touch $f1"
3422         local count=$($LFS getstripe -c $f1)
3423         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3424
3425         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3426         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3427
3428         local maxcount=$(($OSTCOUNT - 1))
3429         local mdts=$(comma_list $(mdts_nodes))
3430         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3431         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3432
3433         local f2="$testdir/f2"
3434         touch $f2 || error "failed to touch $f2"
3435         local count=$($LFS getstripe -c $f2)
3436         (( $count == $maxcount )) || error "wrong stripe count"
3437 }
3438 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3439
3440 test_27T() {
3441         [ $(facet_host client) == $(facet_host ost1) ] &&
3442                 skip "need ost1 and client on different nodes"
3443
3444 #define OBD_FAIL_OSC_NO_GRANT            0x411
3445         $LCTL set_param fail_loc=0x20000411 fail_val=1
3446 #define OBD_FAIL_OST_ENOSPC              0x215
3447         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3448         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3449         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3450                 error "multiop failed"
3451 }
3452 run_test 27T "no eio on close on partial write due to enosp"
3453
3454 test_27U() {
3455         local dir=$DIR/$tdir
3456         local file=$dir/$tfile
3457         local append_pool=${TESTNAME}-append
3458         local normal_pool=${TESTNAME}-normal
3459         local pool
3460         local stripe_count
3461         local stripe_count2
3462         local mdts=$(comma_list $(mdts_nodes))
3463
3464         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3465                 skip "Need MDS version at least 2.15.51 for append pool feature"
3466
3467         # Validate existing append_* params and ensure restore
3468         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3469         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3470         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3471
3472         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3473         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3474         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3475
3476         pool_add $append_pool || error "pool creation failed"
3477         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3478
3479         pool_add $normal_pool || error "pool creation failed"
3480         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3481
3482         test_mkdir $dir
3483         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3484
3485         echo XXX >> $file.1
3486         $LFS getstripe $file.1
3487
3488         pool=$($LFS getstripe -p $file.1)
3489         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3490
3491         stripe_count2=$($LFS getstripe -c $file.1)
3492         ((stripe_count2 == stripe_count)) ||
3493                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3494
3495         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3496
3497         echo XXX >> $file.2
3498         $LFS getstripe $file.2
3499
3500         pool=$($LFS getstripe -p $file.2)
3501         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3502
3503         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3504
3505         echo XXX >> $file.3
3506         $LFS getstripe $file.3
3507
3508         stripe_count2=$($LFS getstripe -c $file.3)
3509         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3510 }
3511 run_test 27U "append pool and stripe count work with composite default layout"
3512
3513 test_27V() {
3514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3515         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3516
3517         local dir=$DIR/$tdir
3518         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3519         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3520         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3521         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3522         local pid
3523
3524         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3525
3526         do_facet mds1 $LCTL set_param $lod_param=0
3527         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3528
3529         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3530         stack_trap "rm -rf $dir"
3531
3532         # exercise race in LU-16981 with deactivating OST while creating a file
3533         (
3534                 while true; do
3535                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3536                         sleep 0.1
3537                         do_facet mds1 \
3538                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3539                 done
3540         ) &
3541
3542         pid=$!
3543         stack_trap "kill -9 $pid"
3544
3545         # errors here are OK so ignore them (just don't want to crash)
3546         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3547
3548         return 0
3549 }
3550 run_test 27V "creating widely striped file races with deactivating OST"
3551
3552 # createtest also checks that device nodes are created and
3553 # then visible correctly (#2091)
3554 test_28() { # bug 2091
3555         test_mkdir $DIR/d28
3556         $CREATETEST $DIR/d28/ct || error "createtest failed"
3557 }
3558 run_test 28 "create/mknod/mkdir with bad file types ============"
3559
3560 test_29() {
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562
3563         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3564                 disable_opencache
3565                 stack_trap "restore_opencache"
3566         }
3567
3568         sync; sleep 1; sync # flush out any dirty pages from previous tests
3569         cancel_lru_locks
3570         test_mkdir $DIR/d29
3571         touch $DIR/d29/foo
3572         log 'first d29'
3573         ls -l $DIR/d29
3574
3575         local locks_orig=$(total_used_locks mdc)
3576         (( $locks_orig != 0 )) || error "No mdc lock count"
3577
3578         local locks_unused_orig=$(total_unused_locks mdc)
3579
3580         log 'second d29'
3581         ls -l $DIR/d29
3582         log 'done'
3583
3584         local locks_current=$(total_used_locks mdc)
3585
3586         local locks_unused_current=$(total_unused_locks mdc)
3587
3588         if (( $locks_current > $locks_orig )); then
3589                 $LCTL set_param -n ldlm.dump_namespaces ""
3590                 error "CURRENT: $locks_current > $locks_orig"
3591         fi
3592         if (( $locks_unused_current > $locks_unused_orig )); then
3593                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3594         fi
3595 }
3596 run_test 29 "IT_GETATTR regression  ============================"
3597
3598 test_30a() { # was test_30
3599         cp $(which ls) $DIR || cp /bin/ls $DIR
3600         $DIR/ls / || error "Can't execute binary from lustre"
3601         rm $DIR/ls
3602 }
3603 run_test 30a "execute binary from Lustre (execve) =============="
3604
3605 test_30b() {
3606         cp `which ls` $DIR || cp /bin/ls $DIR
3607         chmod go+rx $DIR/ls
3608         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3609         rm $DIR/ls
3610 }
3611 run_test 30b "execute binary from Lustre as non-root ==========="
3612
3613 test_30c() { # b=22376
3614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3615
3616         cp $(which ls) $DIR || cp /bin/ls $DIR
3617         chmod a-rw $DIR/ls
3618         cancel_lru_locks mdc
3619         cancel_lru_locks osc
3620         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3621         rm -f $DIR/ls
3622 }
3623 run_test 30c "execute binary from Lustre without read perms ===="
3624
3625 test_30d() {
3626         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3627
3628         for i in {1..10}; do
3629                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3630                 local PID=$!
3631                 sleep 1
3632                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3633                 wait $PID || error "executing dd from Lustre failed"
3634                 rm -f $DIR/$tfile
3635         done
3636
3637         rm -f $DIR/dd
3638 }
3639 run_test 30d "execute binary from Lustre while clear locks"
3640
3641 test_31a() {
3642         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3643         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3644 }
3645 run_test 31a "open-unlink file =================================="
3646
3647 test_31b() {
3648         touch $DIR/f31 || error "touch $DIR/f31 failed"
3649         ln $DIR/f31 $DIR/f31b || error "ln failed"
3650         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3651         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3652 }
3653 run_test 31b "unlink file with multiple links while open ======="
3654
3655 test_31c() {
3656         touch $DIR/f31 || error "touch $DIR/f31 failed"
3657         ln $DIR/f31 $DIR/f31c || error "ln failed"
3658         multiop_bg_pause $DIR/f31 O_uc ||
3659                 error "multiop_bg_pause for $DIR/f31 failed"
3660         MULTIPID=$!
3661         $MULTIOP $DIR/f31c Ouc
3662         kill -USR1 $MULTIPID
3663         wait $MULTIPID
3664 }
3665 run_test 31c "open-unlink file with multiple links ============="
3666
3667 test_31d() {
3668         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3669         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3670 }
3671 run_test 31d "remove of open directory ========================="
3672
3673 test_31e() { # bug 2904
3674         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3675 }
3676 run_test 31e "remove of open non-empty directory ==============="
3677
3678 test_31f() { # bug 4554
3679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3680
3681         set -vx
3682         test_mkdir $DIR/d31f
3683         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3684         cp /etc/hosts $DIR/d31f
3685         ls -l $DIR/d31f
3686         $LFS getstripe $DIR/d31f/hosts
3687         multiop_bg_pause $DIR/d31f D_c || return 1
3688         MULTIPID=$!
3689
3690         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3691         test_mkdir $DIR/d31f
3692         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3693         cp /etc/hosts $DIR/d31f
3694         ls -l $DIR/d31f
3695         $LFS getstripe $DIR/d31f/hosts
3696         multiop_bg_pause $DIR/d31f D_c || return 1
3697         MULTIPID2=$!
3698
3699         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3700         wait $MULTIPID || error "first opendir $MULTIPID failed"
3701
3702         sleep 6
3703
3704         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3705         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3706         set +vx
3707 }
3708 run_test 31f "remove of open directory with open-unlink file ==="
3709
3710 test_31g() {
3711         echo "-- cross directory link --"
3712         test_mkdir -c1 $DIR/${tdir}ga
3713         test_mkdir -c1 $DIR/${tdir}gb
3714         touch $DIR/${tdir}ga/f
3715         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3716         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3717         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3718         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3719         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3720 }
3721 run_test 31g "cross directory link==============="
3722
3723 test_31h() {
3724         echo "-- cross directory link --"
3725         test_mkdir -c1 $DIR/${tdir}
3726         test_mkdir -c1 $DIR/${tdir}/dir
3727         touch $DIR/${tdir}/f
3728         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3729         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3730         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3731         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3732         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3733 }
3734 run_test 31h "cross directory link under child==============="
3735
3736 test_31i() {
3737         echo "-- cross directory link --"
3738         test_mkdir -c1 $DIR/$tdir
3739         test_mkdir -c1 $DIR/$tdir/dir
3740         touch $DIR/$tdir/dir/f
3741         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3742         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3743         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3744         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3745         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3746 }
3747 run_test 31i "cross directory link under parent==============="
3748
3749 test_31j() {
3750         test_mkdir -c1 -p $DIR/$tdir
3751         test_mkdir -c1 -p $DIR/$tdir/dir1
3752         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3753         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3754         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3755         return 0
3756 }
3757 run_test 31j "link for directory"
3758
3759 test_31k() {
3760         test_mkdir -c1 -p $DIR/$tdir
3761         touch $DIR/$tdir/s
3762         touch $DIR/$tdir/exist
3763         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3764         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3765         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3766         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3767         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3768         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3769         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3770         return 0
3771 }
3772 run_test 31k "link to file: the same, non-existing, dir"
3773
3774 test_31l() {
3775         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3776
3777         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3778         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3779                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3780
3781         touch $DIR/$tfile || error "create failed"
3782         mkdir $DIR/$tdir || error "mkdir failed"
3783         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3784 }
3785 run_test 31l "link to file: target dir has trailing slash"
3786
3787 test_31m() {
3788         mkdir $DIR/d31m
3789         touch $DIR/d31m/s
3790         mkdir $DIR/d31m2
3791         touch $DIR/d31m2/exist
3792         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3793         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3794         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3795         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3796         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3797         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3798         return 0
3799 }
3800 run_test 31m "link to file: the same, non-existing, dir"
3801
3802 test_31n() {
3803         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3804         nlink=$(stat --format=%h $DIR/$tfile)
3805         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3806         local fd=$(free_fd)
3807         local cmd="exec $fd<$DIR/$tfile"
3808         eval $cmd
3809         cmd="exec $fd<&-"
3810         trap "eval $cmd" EXIT
3811         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3812         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3813         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3814         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3815         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3816         eval $cmd
3817 }
3818 run_test 31n "check link count of unlinked file"
3819
3820 link_one() {
3821         local tempfile=$(mktemp $1_XXXXXX)
3822         link $tempfile $1 2> /dev/null &&
3823                 echo "$BASHPID: link $tempfile to $1 succeeded"
3824         unlink $tempfile
3825 }
3826
3827 test_31o() { # LU-2901
3828         test_mkdir $DIR/$tdir
3829         for LOOP in $(seq 100); do
3830                 rm -f $DIR/$tdir/$tfile*
3831                 for THREAD in $(seq 8); do
3832                         link_one $DIR/$tdir/$tfile.$LOOP &
3833                 done
3834                 wait
3835                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3836                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3837                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3838                         break || true
3839         done
3840 }
3841 run_test 31o "duplicate hard links with same filename"
3842
3843 test_31p() {
3844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3845
3846         test_mkdir $DIR/$tdir
3847         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3848         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3849
3850         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3851                 error "open unlink test1 failed"
3852         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3853                 error "open unlink test2 failed"
3854
3855         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3856                 error "test1 still exists"
3857         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3858                 error "test2 still exists"
3859 }
3860 run_test 31p "remove of open striped directory"
3861
3862 test_31q() {
3863         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3864
3865         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3866         index=$($LFS getdirstripe -i $DIR/$tdir)
3867         [ $index -eq 3 ] || error "first stripe index $index != 3"
3868         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3869         [ $index -eq 1 ] || error "second stripe index $index != 1"
3870
3871         # when "-c <stripe_count>" is set, the number of MDTs specified after
3872         # "-i" should equal to the stripe count
3873         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3874 }
3875 run_test 31q "create striped directory on specific MDTs"
3876
3877 #LU-14949
3878 test_31r() {
3879         touch $DIR/$tfile.target
3880         touch $DIR/$tfile.source
3881
3882         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3883         $LCTL set_param fail_loc=0x1419 fail_val=3
3884         cat $DIR/$tfile.target &
3885         CATPID=$!
3886
3887         # Guarantee open is waiting before we get here
3888         sleep 1
3889         mv $DIR/$tfile.source $DIR/$tfile.target
3890
3891         wait $CATPID
3892         RC=$?
3893         if [[ $RC -ne 0 ]]; then
3894                 error "open with cat failed, rc=$RC"
3895         fi
3896 }
3897 run_test 31r "open-rename(replace) race"
3898
3899 cleanup_test32_mount() {
3900         local rc=0
3901         trap 0
3902         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3903         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3904         losetup -d $loopdev || true
3905         rm -rf $DIR/$tdir
3906         return $rc
3907 }
3908
3909 test_32a() {
3910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3911
3912         echo "== more mountpoints and symlinks ================="
3913         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3914         trap cleanup_test32_mount EXIT
3915         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3916         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3917                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3918         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3919                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3920         cleanup_test32_mount
3921 }
3922 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3923
3924 test_32b() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3933                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3934         cleanup_test32_mount
3935 }
3936 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3937
3938 test_32c() {
3939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3940
3941         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3942         trap cleanup_test32_mount EXIT
3943         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         test_mkdir -p $DIR/$tdir/d2/test_dir
3947         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3948                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3949         cleanup_test32_mount
3950 }
3951 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3952
3953 test_32d() {
3954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3955
3956         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3957         trap cleanup_test32_mount EXIT
3958         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3959         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3960                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3961         test_mkdir -p $DIR/$tdir/d2/test_dir
3962         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3963                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3964         cleanup_test32_mount
3965 }
3966 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3967
3968 test_32e() {
3969         rm -fr $DIR/$tdir
3970         test_mkdir -p $DIR/$tdir/tmp
3971         local tmp_dir=$DIR/$tdir/tmp
3972         ln -s $DIR/$tdir $tmp_dir/symlink11
3973         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3974         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3975         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3976 }
3977 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3978
3979 test_32f() {
3980         rm -fr $DIR/$tdir
3981         test_mkdir -p $DIR/$tdir/tmp
3982         local tmp_dir=$DIR/$tdir/tmp
3983         ln -s $DIR/$tdir $tmp_dir/symlink11
3984         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3985         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3986         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3987 }
3988 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3989
3990 test_32g() {
3991         local tmp_dir=$DIR/$tdir/tmp
3992         test_mkdir -p $tmp_dir
3993         test_mkdir $DIR/${tdir}2
3994         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3995         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3996         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3997         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3998         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3999         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4000 }
4001 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4002
4003 test_32h() {
4004         rm -fr $DIR/$tdir $DIR/${tdir}2
4005         tmp_dir=$DIR/$tdir/tmp
4006         test_mkdir -p $tmp_dir
4007         test_mkdir $DIR/${tdir}2
4008         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4009         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4010         ls $tmp_dir/symlink12 || error "listing symlink12"
4011         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4012 }
4013 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4014
4015 test_32i() {
4016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4017
4018         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4019         trap cleanup_test32_mount EXIT
4020         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4021         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4022                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4023         touch $DIR/$tdir/test_file
4024         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4025                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4026         cleanup_test32_mount
4027 }
4028 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4029
4030 test_32j() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032
4033         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4034         trap cleanup_test32_mount EXIT
4035         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4036         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4037                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4038         touch $DIR/$tdir/test_file
4039         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4040                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4041         cleanup_test32_mount
4042 }
4043 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4044
4045 test_32k() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         test_mkdir -p $DIR/$tdir/d2
4054         touch $DIR/$tdir/d2/test_file || error "touch failed"
4055         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4056                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4057         cleanup_test32_mount
4058 }
4059 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4060
4061 test_32l() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         rm -fr $DIR/$tdir
4065         trap cleanup_test32_mount EXIT
4066         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4067         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4068                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4069         test_mkdir -p $DIR/$tdir/d2
4070         touch $DIR/$tdir/d2/test_file || error "touch failed"
4071         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4072                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4073         cleanup_test32_mount
4074 }
4075 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4076
4077 test_32m() {
4078         rm -fr $DIR/d32m
4079         test_mkdir -p $DIR/d32m/tmp
4080         TMP_DIR=$DIR/d32m/tmp
4081         ln -s $DIR $TMP_DIR/symlink11
4082         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4083         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4084                 error "symlink11 not a link"
4085         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4086                 error "symlink01 not a link"
4087 }
4088 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4089
4090 test_32n() {
4091         rm -fr $DIR/d32n
4092         test_mkdir -p $DIR/d32n/tmp
4093         TMP_DIR=$DIR/d32n/tmp
4094         ln -s $DIR $TMP_DIR/symlink11
4095         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4096         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4097         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4098 }
4099 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4100
4101 test_32o() {
4102         touch $DIR/$tfile
4103         test_mkdir -p $DIR/d32o/tmp
4104         TMP_DIR=$DIR/d32o/tmp
4105         ln -s $DIR/$tfile $TMP_DIR/symlink12
4106         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4107         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4108                 error "symlink12 not a link"
4109         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4110         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4111                 error "$DIR/d32o/tmp/symlink12 not file type"
4112         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4113                 error "$DIR/d32o/symlink02 not file type"
4114 }
4115 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4116
4117 test_32p() {
4118         log 32p_1
4119         rm -fr $DIR/d32p
4120         log 32p_2
4121         rm -f $DIR/$tfile
4122         log 32p_3
4123         touch $DIR/$tfile
4124         log 32p_4
4125         test_mkdir -p $DIR/d32p/tmp
4126         log 32p_5
4127         TMP_DIR=$DIR/d32p/tmp
4128         log 32p_6
4129         ln -s $DIR/$tfile $TMP_DIR/symlink12
4130         log 32p_7
4131         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4132         log 32p_8
4133         cat $DIR/d32p/tmp/symlink12 ||
4134                 error "Can't open $DIR/d32p/tmp/symlink12"
4135         log 32p_9
4136         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4137         log 32p_10
4138 }
4139 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4140
4141 test_32q() {
4142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4143
4144         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4145         trap cleanup_test32_mount EXIT
4146         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4147         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4148         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4149                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4150         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4151         cleanup_test32_mount
4152 }
4153 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4154
4155 test_32r() {
4156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4157
4158         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4159         trap cleanup_test32_mount EXIT
4160         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4161         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4162         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4163                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4164         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4165         cleanup_test32_mount
4166 }
4167 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4168
4169 test_33aa() {
4170         rm -f $DIR/$tfile
4171         touch $DIR/$tfile
4172         chmod 444 $DIR/$tfile
4173         chown $RUNAS_ID $DIR/$tfile
4174         log 33_1
4175         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4176         log 33_2
4177 }
4178 run_test 33aa "write file with mode 444 (should return error)"
4179
4180 test_33a() {
4181         rm -fr $DIR/$tdir
4182         test_mkdir $DIR/$tdir
4183         chown $RUNAS_ID $DIR/$tdir
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4185                 error "$RUNAS create $tdir/$tfile failed"
4186         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4187                 error "open RDWR" || true
4188 }
4189 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4190
4191 test_33b() {
4192         rm -fr $DIR/$tdir
4193         test_mkdir $DIR/$tdir
4194         chown $RUNAS_ID $DIR/$tdir
4195         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4196 }
4197 run_test 33b "test open file with malformed flags (No panic)"
4198
4199 test_33c() {
4200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4201         remote_ost_nodsh && skip "remote OST with nodsh"
4202
4203         local ostnum
4204         local ostname
4205         local write_bytes
4206         local all_zeros
4207
4208         all_zeros=true
4209         test_mkdir $DIR/$tdir
4210         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4211
4212         sync
4213         for ostnum in $(seq $OSTCOUNT); do
4214                 # test-framework's OST numbering is one-based, while Lustre's
4215                 # is zero-based
4216                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4217                 # check if at least some write_bytes stats are counted
4218                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4219                               obdfilter.$ostname.stats |
4220                               awk '/^write_bytes/ {print $7}' )
4221                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4222                 if (( ${write_bytes:-0} > 0 )); then
4223                         all_zeros=false
4224                         break
4225                 fi
4226         done
4227
4228         $all_zeros || return 0
4229
4230         # Write four bytes
4231         echo foo > $DIR/$tdir/bar
4232         # Really write them
4233         sync
4234
4235         # Total up write_bytes after writing.  We'd better find non-zeros.
4236         for ostnum in $(seq $OSTCOUNT); do
4237                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4238                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4239                               obdfilter/$ostname/stats |
4240                               awk '/^write_bytes/ {print $7}' )
4241                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4242                 if (( ${write_bytes:-0} > 0 )); then
4243                         all_zeros=false
4244                         break
4245                 fi
4246         done
4247
4248         if $all_zeros; then
4249                 for ostnum in $(seq $OSTCOUNT); do
4250                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4251                         echo "Check write_bytes is in obdfilter.*.stats:"
4252                         do_facet ost$ostnum lctl get_param -n \
4253                                 obdfilter.$ostname.stats
4254                 done
4255                 error "OST not keeping write_bytes stats (b=22312)"
4256         fi
4257 }
4258 run_test 33c "test write_bytes stats"
4259
4260 test_33d() {
4261         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4263
4264         local MDTIDX=1
4265         local remote_dir=$DIR/$tdir/remote_dir
4266
4267         test_mkdir $DIR/$tdir
4268         $LFS mkdir -i $MDTIDX $remote_dir ||
4269                 error "create remote directory failed"
4270
4271         touch $remote_dir/$tfile
4272         chmod 444 $remote_dir/$tfile
4273         chown $RUNAS_ID $remote_dir/$tfile
4274
4275         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4276
4277         chown $RUNAS_ID $remote_dir
4278         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4279                                         error "create" || true
4280         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4281                                     error "open RDWR" || true
4282         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4283 }
4284 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4285
4286 test_33e() {
4287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4288
4289         mkdir $DIR/$tdir
4290
4291         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4292         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4293         mkdir $DIR/$tdir/local_dir
4294
4295         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4296         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4297         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4298
4299         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4300                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4301
4302         rmdir $DIR/$tdir/* || error "rmdir failed"
4303
4304         umask 777
4305         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4306         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4307         mkdir $DIR/$tdir/local_dir
4308
4309         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4310         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4311         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4312
4313         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4314                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4315
4316         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4317
4318         umask 000
4319         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4320         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4321         mkdir $DIR/$tdir/local_dir
4322
4323         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4324         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4325         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4326
4327         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4328                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4329 }
4330 run_test 33e "mkdir and striped directory should have same mode"
4331
4332 cleanup_33f() {
4333         trap 0
4334         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4335 }
4336
4337 test_33f() {
4338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4339         remote_mds_nodsh && skip "remote MDS with nodsh"
4340
4341         mkdir $DIR/$tdir
4342         chmod go+rwx $DIR/$tdir
4343         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4344         trap cleanup_33f EXIT
4345
4346         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4347                 error "cannot create striped directory"
4348
4349         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4350                 error "cannot create files in striped directory"
4351
4352         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4353                 error "cannot remove files in striped directory"
4354
4355         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4356                 error "cannot remove striped directory"
4357
4358         cleanup_33f
4359 }
4360 run_test 33f "nonroot user can create, access, and remove a striped directory"
4361
4362 test_33g() {
4363         mkdir -p $DIR/$tdir/dir2
4364
4365         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4366         echo $err
4367         [[ $err =~ "exists" ]] || error "Not exists error"
4368 }
4369 run_test 33g "nonroot user create already existing root created file"
4370
4371 sub_33h() {
4372         local hash_type=$1
4373         local count=250
4374
4375         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4376                 error "lfs mkdir -H $hash_type $tdir failed"
4377         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4378
4379         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4380         local index2
4381         local fname
4382
4383         for fname in $DIR/$tdir/$tfile.bak \
4384                      $DIR/$tdir/$tfile.SAV \
4385                      $DIR/$tdir/$tfile.orig \
4386                      $DIR/$tdir/$tfile~; do
4387                 touch $fname || error "touch $fname failed"
4388                 index2=$($LFS getstripe -m $fname)
4389                 (( $index == $index2 )) ||
4390                         error "$fname MDT index mismatch $index != $index2"
4391         done
4392
4393         local failed=0
4394         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4395         local pattern
4396
4397         for pattern in ${patterns[*]}; do
4398                 echo "pattern $pattern"
4399                 fname=$DIR/$tdir/$pattern
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4402                                 error "mktemp $DIR/$tdir/$pattern failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index == $index2 )) && continue
4405
4406                         failed=$((failed + 1))
4407                         echo "$fname MDT index mismatch $index != $index2"
4408                 done
4409         done
4410
4411         echo "$failed/$count MDT index mismatches, expect ~2-4"
4412         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4413
4414         local same=0
4415         local expect
4416
4417         # verify that "crush" is still broken with all files on same MDT,
4418         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4419         [[ "$hash_type" == "crush" ]] && expect=$count ||
4420                 expect=$((count / MDSCOUNT))
4421
4422         # crush2 doesn't put all-numeric suffixes on the same MDT,
4423         # filename like $tfile.12345678 should *not* be considered temp
4424         for pattern in ${patterns[*]}; do
4425                 local base=${pattern%%X*}
4426                 local suff=${pattern#$base}
4427
4428                 echo "pattern $pattern"
4429                 for (( i = 0; i < $count; i++ )); do
4430                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4431                         touch $fname || error "touch $fname failed"
4432                         index2=$($LFS getstripe -m $fname)
4433                         (( $index != $index2 )) && continue
4434
4435                         same=$((same + 1))
4436                 done
4437         done
4438
4439         # the number of "bad" hashes is random, as it depends on the random
4440         # filenames generated by "mktemp".  Allow some margin in the results.
4441         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4442         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4443            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4444                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4445         same=0
4446
4447         # crush2 doesn't put suffixes with special characters on the same MDT
4448         # filename like $tfile.txt.1234 should *not* be considered temp
4449         for pattern in ${patterns[*]}; do
4450                 local base=${pattern%%X*}
4451                 local suff=${pattern#$base}
4452
4453                 pattern=$base...${suff/XXX}
4454                 echo "pattern=$pattern"
4455                 for (( i = 0; i < $count; i++ )); do
4456                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4457                                 error "touch $fname failed"
4458                         index2=$($LFS getstripe -m $fname)
4459                         (( $index != $index2 )) && continue
4460
4461                         same=$((same + 1))
4462                 done
4463         done
4464
4465         # the number of "bad" hashes is random, as it depends on the random
4466         # filenames generated by "mktemp".  Allow some margin in the results.
4467         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4468         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4469            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4470                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4471 }
4472
4473 test_33h() {
4474         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4475         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4476                 skip "Need MDS version at least 2.13.50"
4477
4478         sub_33h crush
4479 }
4480 run_test 33h "temp file is located on the same MDT as target (crush)"
4481
4482 test_33hh() {
4483         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4484         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4485         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4486                 skip "Need MDS version at least 2.15.0 for crush2"
4487
4488         sub_33h crush2
4489 }
4490 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4491
4492 test_33i()
4493 {
4494         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4495
4496         local FNAME=$(str_repeat 'f' 250)
4497
4498         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4499         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4500
4501         local count
4502         local total
4503
4504         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4505
4506         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4507
4508         lctl --device %$MDC deactivate
4509         stack_trap "lctl --device %$MDC activate"
4510         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4511         total=$(\ls -l $DIR/$tdir | wc -l)
4512         # "ls -l" will list total in the first line
4513         total=$((total - 1))
4514         (( total + count == 1000 )) ||
4515                 error "ls list $total files, $count files on MDT1"
4516 }
4517 run_test 33i "striped directory can be accessed when one MDT is down"
4518
4519 test_33j() {
4520         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4521
4522         mkdir -p $DIR/$tdir/
4523
4524         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4525                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4526
4527         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4528                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4529
4530         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4531                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4532
4533         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4534                 error "-D was not specified, but still failed"
4535 }
4536 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4537
4538 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4539 test_34a() {
4540         rm -f $DIR/f34
4541         $MCREATE $DIR/f34 || error "mcreate failed"
4542         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4543                 error "getstripe failed"
4544         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4545         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4546                 error "getstripe failed"
4547         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4548                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4549 }
4550 run_test 34a "truncate file that has not been opened ==========="
4551
4552 test_34b() {
4553         [ ! -f $DIR/f34 ] && test_34a
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556         $OPENFILE -f O_RDONLY $DIR/f34
4557         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4558                 error "getstripe failed"
4559         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4560                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4561 }
4562 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4563
4564 test_34c() {
4565         [ ! -f $DIR/f34 ] && test_34a
4566         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4567                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4568         $OPENFILE -f O_RDWR $DIR/f34
4569         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4570                 error "$LFS getstripe failed"
4571         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4572                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4573 }
4574 run_test 34c "O_RDWR opening file-with-size works =============="
4575
4576 test_34d() {
4577         [ ! -f $DIR/f34 ] && test_34a
4578         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4579                 error "dd failed"
4580         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4581                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4582         rm $DIR/f34
4583 }
4584 run_test 34d "write to sparse file ============================="
4585
4586 test_34e() {
4587         rm -f $DIR/f34e
4588         $MCREATE $DIR/f34e || error "mcreate failed"
4589         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4590         $CHECKSTAT -s 1000 $DIR/f34e ||
4591                 error "Size of $DIR/f34e not equal to 1000 bytes"
4592         $OPENFILE -f O_RDWR $DIR/f34e
4593         $CHECKSTAT -s 1000 $DIR/f34e ||
4594                 error "Size of $DIR/f34e not equal to 1000 bytes"
4595 }
4596 run_test 34e "create objects, some with size and some without =="
4597
4598 test_34f() { # bug 6242, 6243
4599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4600
4601         SIZE34F=48000
4602         rm -f $DIR/f34f
4603         $MCREATE $DIR/f34f || error "mcreate failed"
4604         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4605         dd if=$DIR/f34f of=$TMP/f34f
4606         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4607         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4608         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4609         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4610         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4611 }
4612 run_test 34f "read from a file with no objects until EOF ======="
4613
4614 test_34g() {
4615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4616
4617         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4618                 error "dd failed"
4619         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4620         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4621                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4622         cancel_lru_locks osc
4623         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4624                 error "wrong size after lock cancel"
4625
4626         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4627         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4628                 error "expanding truncate failed"
4629         cancel_lru_locks osc
4630         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4631                 error "wrong expanded size after lock cancel"
4632 }
4633 run_test 34g "truncate long file ==============================="
4634
4635 test_34h() {
4636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4637
4638         local gid=10
4639         local sz=1000
4640
4641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4642         sync # Flush the cache so that multiop below does not block on cache
4643              # flush when getting the group lock
4644         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4645         MULTIPID=$!
4646
4647         # Since just timed wait is not good enough, let's do a sync write
4648         # that way we are sure enough time for a roundtrip + processing
4649         # passed + 2 seconds of extra margin.
4650         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4651         rm $DIR/${tfile}-1
4652         sleep 2
4653
4654         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4655                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4656                 kill -9 $MULTIPID
4657         fi
4658         wait $MULTIPID
4659         local nsz=`stat -c %s $DIR/$tfile`
4660         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4661 }
4662 run_test 34h "ftruncate file under grouplock should not block"
4663
4664 test_35a() {
4665         cp /bin/sh $DIR/f35a
4666         chmod 444 $DIR/f35a
4667         chown $RUNAS_ID $DIR/f35a
4668         $RUNAS $DIR/f35a && error || true
4669         rm $DIR/f35a
4670 }
4671 run_test 35a "exec file with mode 444 (should return and not leak)"
4672
4673 test_36a() {
4674         rm -f $DIR/f36
4675         utime $DIR/f36 || error "utime failed for MDS"
4676 }
4677 run_test 36a "MDS utime check (mknod, utime)"
4678
4679 test_36b() {
4680         echo "" > $DIR/f36
4681         utime $DIR/f36 || error "utime failed for OST"
4682 }
4683 run_test 36b "OST utime check (open, utime)"
4684
4685 test_36c() {
4686         rm -f $DIR/d36/f36
4687         test_mkdir $DIR/d36
4688         chown $RUNAS_ID $DIR/d36
4689         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4690 }
4691 run_test 36c "non-root MDS utime check (mknod, utime)"
4692
4693 test_36d() {
4694         [ ! -d $DIR/d36 ] && test_36c
4695         echo "" > $DIR/d36/f36
4696         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4697 }
4698 run_test 36d "non-root OST utime check (open, utime)"
4699
4700 test_36e() {
4701         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4702
4703         test_mkdir $DIR/$tdir
4704         touch $DIR/$tdir/$tfile
4705         $RUNAS utime $DIR/$tdir/$tfile &&
4706                 error "utime worked, expected failure" || true
4707 }
4708 run_test 36e "utime on non-owned file (should return error)"
4709
4710 subr_36fh() {
4711         local fl="$1"
4712         local LANG_SAVE=$LANG
4713         local LC_LANG_SAVE=$LC_LANG
4714         export LANG=C LC_LANG=C # for date language
4715
4716         DATESTR="Dec 20  2000"
4717         test_mkdir $DIR/$tdir
4718         lctl set_param fail_loc=$fl
4719         date; date +%s
4720         cp /etc/hosts $DIR/$tdir/$tfile
4721         sync & # write RPC generated with "current" inode timestamp, but delayed
4722         sleep 1
4723         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4724         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4725         cancel_lru_locks $OSC
4726         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4727         date; date +%s
4728         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4729                 echo "BEFORE: $LS_BEFORE" && \
4730                 echo "AFTER : $LS_AFTER" && \
4731                 echo "WANT  : $DATESTR" && \
4732                 error "$DIR/$tdir/$tfile timestamps changed" || true
4733
4734         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4735 }
4736
4737 test_36f() {
4738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4739
4740         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4741         subr_36fh "0x80000214"
4742 }
4743 run_test 36f "utime on file racing with OST BRW write =========="
4744
4745 test_36g() {
4746         remote_ost_nodsh && skip "remote OST with nodsh"
4747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4748         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4749                 skip "Need MDS version at least 2.12.51"
4750
4751         local fmd_max_age
4752         local fmd
4753         local facet="ost1"
4754         local tgt="obdfilter"
4755
4756         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4757
4758         test_mkdir $DIR/$tdir
4759         fmd_max_age=$(do_facet $facet \
4760                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4761                 head -n 1")
4762
4763         echo "FMD max age: ${fmd_max_age}s"
4764         touch $DIR/$tdir/$tfile
4765         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4766                 gawk '{cnt=cnt+$1}  END{print cnt}')
4767         echo "FMD before: $fmd"
4768         [[ $fmd == 0 ]] &&
4769                 error "FMD wasn't create by touch"
4770         sleep $((fmd_max_age + 12))
4771         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4772                 gawk '{cnt=cnt+$1}  END{print cnt}')
4773         echo "FMD after: $fmd"
4774         [[ $fmd == 0 ]] ||
4775                 error "FMD wasn't expired by ping"
4776 }
4777 run_test 36g "FMD cache expiry ====================="
4778
4779 test_36h() {
4780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4781
4782         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4783         subr_36fh "0x80000227"
4784 }
4785 run_test 36h "utime on file racing with OST BRW write =========="
4786
4787 test_36i() {
4788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4789
4790         test_mkdir $DIR/$tdir
4791         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4792
4793         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4794         local new_mtime=$((mtime + 200))
4795
4796         #change Modify time of striped dir
4797         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4798                         error "change mtime failed"
4799
4800         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4801
4802         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4803 }
4804 run_test 36i "change mtime on striped directory"
4805
4806 # test_37 - duplicate with tests 32q 32r
4807
4808 test_38() {
4809         local file=$DIR/$tfile
4810         touch $file
4811         openfile -f O_DIRECTORY $file
4812         local RC=$?
4813         local ENOTDIR=20
4814         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4815         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4816 }
4817 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4818
4819 test_39a() { # was test_39
4820         touch $DIR/$tfile
4821         touch $DIR/${tfile}2
4822 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4823 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4824 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4825         sleep 2
4826         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4827         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4828                 echo "mtime"
4829                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4830                 echo "atime"
4831                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4832                 echo "ctime"
4833                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4834                 error "O_TRUNC didn't change timestamps"
4835         fi
4836 }
4837 run_test 39a "mtime changed on create"
4838
4839 test_39b() {
4840         test_mkdir -c1 $DIR/$tdir
4841         cp -p /etc/passwd $DIR/$tdir/fopen
4842         cp -p /etc/passwd $DIR/$tdir/flink
4843         cp -p /etc/passwd $DIR/$tdir/funlink
4844         cp -p /etc/passwd $DIR/$tdir/frename
4845         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4846
4847         sleep 1
4848         echo "aaaaaa" >> $DIR/$tdir/fopen
4849         echo "aaaaaa" >> $DIR/$tdir/flink
4850         echo "aaaaaa" >> $DIR/$tdir/funlink
4851         echo "aaaaaa" >> $DIR/$tdir/frename
4852
4853         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4854         local link_new=`stat -c %Y $DIR/$tdir/flink`
4855         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4856         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4857
4858         cat $DIR/$tdir/fopen > /dev/null
4859         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4860         rm -f $DIR/$tdir/funlink2
4861         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4862
4863         for (( i=0; i < 2; i++ )) ; do
4864                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4865                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4866                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4867                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4868
4869                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4870                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4871                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4872                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4873
4874                 cancel_lru_locks $OSC
4875                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4876         done
4877 }
4878 run_test 39b "mtime change on open, link, unlink, rename  ======"
4879
4880 # this should be set to past
4881 TEST_39_MTIME=`date -d "1 year ago" +%s`
4882
4883 # bug 11063
4884 test_39c() {
4885         touch $DIR1/$tfile
4886         sleep 2
4887         local mtime0=`stat -c %Y $DIR1/$tfile`
4888
4889         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4890         local mtime1=`stat -c %Y $DIR1/$tfile`
4891         [ "$mtime1" = $TEST_39_MTIME ] || \
4892                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4893
4894         local d1=`date +%s`
4895         echo hello >> $DIR1/$tfile
4896         local d2=`date +%s`
4897         local mtime2=`stat -c %Y $DIR1/$tfile`
4898         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4899                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4900
4901         mv $DIR1/$tfile $DIR1/$tfile-1
4902
4903         for (( i=0; i < 2; i++ )) ; do
4904                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4905                 [ "$mtime2" = "$mtime3" ] || \
4906                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4907
4908                 cancel_lru_locks $OSC
4909                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4910         done
4911 }
4912 run_test 39c "mtime change on rename ==========================="
4913
4914 # bug 21114
4915 test_39d() {
4916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4917
4918         touch $DIR1/$tfile
4919         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4920
4921         for (( i=0; i < 2; i++ )) ; do
4922                 local mtime=`stat -c %Y $DIR1/$tfile`
4923                 [ $mtime = $TEST_39_MTIME ] || \
4924                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4925
4926                 cancel_lru_locks $OSC
4927                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4928         done
4929 }
4930 run_test 39d "create, utime, stat =============================="
4931
4932 # bug 21114
4933 test_39e() {
4934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4935
4936         touch $DIR1/$tfile
4937         local mtime1=`stat -c %Y $DIR1/$tfile`
4938
4939         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4940
4941         for (( i=0; i < 2; i++ )) ; do
4942                 local mtime2=`stat -c %Y $DIR1/$tfile`
4943                 [ $mtime2 = $TEST_39_MTIME ] || \
4944                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4945
4946                 cancel_lru_locks $OSC
4947                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4948         done
4949 }
4950 run_test 39e "create, stat, utime, stat ========================"
4951
4952 # bug 21114
4953 test_39f() {
4954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4955
4956         touch $DIR1/$tfile
4957         mtime1=`stat -c %Y $DIR1/$tfile`
4958
4959         sleep 2
4960         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4961
4962         for (( i=0; i < 2; i++ )) ; do
4963                 local mtime2=`stat -c %Y $DIR1/$tfile`
4964                 [ $mtime2 = $TEST_39_MTIME ] || \
4965                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4966
4967                 cancel_lru_locks $OSC
4968                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4969         done
4970 }
4971 run_test 39f "create, stat, sleep, utime, stat ================="
4972
4973 # bug 11063
4974 test_39g() {
4975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4976
4977         echo hello >> $DIR1/$tfile
4978         local mtime1=`stat -c %Y $DIR1/$tfile`
4979
4980         sleep 2
4981         chmod o+r $DIR1/$tfile
4982
4983         for (( i=0; i < 2; i++ )) ; do
4984                 local mtime2=`stat -c %Y $DIR1/$tfile`
4985                 [ "$mtime1" = "$mtime2" ] || \
4986                         error "lost mtime: $mtime2, should be $mtime1"
4987
4988                 cancel_lru_locks $OSC
4989                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4990         done
4991 }
4992 run_test 39g "write, chmod, stat ==============================="
4993
4994 # bug 11063
4995 test_39h() {
4996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4997
4998         touch $DIR1/$tfile
4999         sleep 1
5000
5001         local d1=`date`
5002         echo hello >> $DIR1/$tfile
5003         local mtime1=`stat -c %Y $DIR1/$tfile`
5004
5005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5006         local d2=`date`
5007         if [ "$d1" != "$d2" ]; then
5008                 echo "write and touch not within one second"
5009         else
5010                 for (( i=0; i < 2; i++ )) ; do
5011                         local mtime2=`stat -c %Y $DIR1/$tfile`
5012                         [ "$mtime2" = $TEST_39_MTIME ] || \
5013                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5014
5015                         cancel_lru_locks $OSC
5016                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017                 done
5018         fi
5019 }
5020 run_test 39h "write, utime within one second, stat ============="
5021
5022 test_39i() {
5023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5024
5025         touch $DIR1/$tfile
5026         sleep 1
5027
5028         echo hello >> $DIR1/$tfile
5029         local mtime1=`stat -c %Y $DIR1/$tfile`
5030
5031         mv $DIR1/$tfile $DIR1/$tfile-1
5032
5033         for (( i=0; i < 2; i++ )) ; do
5034                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5035
5036                 [ "$mtime1" = "$mtime2" ] || \
5037                         error "lost mtime: $mtime2, should be $mtime1"
5038
5039                 cancel_lru_locks $OSC
5040                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5041         done
5042 }
5043 run_test 39i "write, rename, stat =============================="
5044
5045 test_39j() {
5046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5047
5048         start_full_debug_logging
5049         touch $DIR1/$tfile
5050         sleep 1
5051
5052         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5053         lctl set_param fail_loc=0x80000412
5054         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5055                 error "multiop failed"
5056         local multipid=$!
5057         local mtime1=`stat -c %Y $DIR1/$tfile`
5058
5059         mv $DIR1/$tfile $DIR1/$tfile-1
5060
5061         kill -USR1 $multipid
5062         wait $multipid || error "multiop close failed"
5063
5064         for (( i=0; i < 2; i++ )) ; do
5065                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5066                 [ "$mtime1" = "$mtime2" ] ||
5067                         error "mtime is lost on close: $mtime2, " \
5068                               "should be $mtime1"
5069
5070                 cancel_lru_locks
5071                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5072         done
5073         lctl set_param fail_loc=0
5074         stop_full_debug_logging
5075 }
5076 run_test 39j "write, rename, close, stat ======================="
5077
5078 test_39k() {
5079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5080
5081         touch $DIR1/$tfile
5082         sleep 1
5083
5084         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5085         local multipid=$!
5086         local mtime1=`stat -c %Y $DIR1/$tfile`
5087
5088         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5089
5090         kill -USR1 $multipid
5091         wait $multipid || error "multiop close failed"
5092
5093         for (( i=0; i < 2; i++ )) ; do
5094                 local mtime2=`stat -c %Y $DIR1/$tfile`
5095
5096                 [ "$mtime2" = $TEST_39_MTIME ] || \
5097                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5098
5099                 cancel_lru_locks
5100                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5101         done
5102 }
5103 run_test 39k "write, utime, close, stat ========================"
5104
5105 # this should be set to future
5106 TEST_39_ATIME=`date -d "1 year" +%s`
5107
5108 test_39l() {
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110         remote_mds_nodsh && skip "remote MDS with nodsh"
5111
5112         local atime_diff=$(do_facet $SINGLEMDS \
5113                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5114         rm -rf $DIR/$tdir
5115         mkdir_on_mdt0 $DIR/$tdir
5116
5117         # test setting directory atime to future
5118         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5119         local atime=$(stat -c %X $DIR/$tdir)
5120         [ "$atime" = $TEST_39_ATIME ] ||
5121                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5122
5123         # test setting directory atime from future to now
5124         local now=$(date +%s)
5125         touch -a -d @$now $DIR/$tdir
5126
5127         atime=$(stat -c %X $DIR/$tdir)
5128         [ "$atime" -eq "$now"  ] ||
5129                 error "atime is not updated from future: $atime, $now"
5130
5131         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5132         sleep 3
5133
5134         # test setting directory atime when now > dir atime + atime_diff
5135         local d1=$(date +%s)
5136         ls $DIR/$tdir
5137         local d2=$(date +%s)
5138         cancel_lru_locks mdc
5139         atime=$(stat -c %X $DIR/$tdir)
5140         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5141                 error "atime is not updated  : $atime, should be $d2"
5142
5143         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5144         sleep 3
5145
5146         # test not setting directory atime when now < dir atime + atime_diff
5147         ls $DIR/$tdir
5148         cancel_lru_locks mdc
5149         atime=$(stat -c %X $DIR/$tdir)
5150         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5151                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5152
5153         do_facet $SINGLEMDS \
5154                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5155 }
5156 run_test 39l "directory atime update ==========================="
5157
5158 test_39m() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         touch $DIR1/$tfile
5162         sleep 2
5163         local far_past_mtime=$(date -d "May 29 1953" +%s)
5164         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5165
5166         touch -m -d @$far_past_mtime $DIR1/$tfile
5167         touch -a -d @$far_past_atime $DIR1/$tfile
5168
5169         for (( i=0; i < 2; i++ )) ; do
5170                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5171                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5172                         error "atime or mtime set incorrectly"
5173
5174                 cancel_lru_locks $OSC
5175                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5176         done
5177 }
5178 run_test 39m "test atime and mtime before 1970"
5179
5180 test_39n() { # LU-3832
5181         remote_mds_nodsh && skip "remote MDS with nodsh"
5182
5183         local atime_diff=$(do_facet $SINGLEMDS \
5184                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5185         local atime0
5186         local atime1
5187         local atime2
5188
5189         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5190
5191         rm -rf $DIR/$tfile
5192         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5193         atime0=$(stat -c %X $DIR/$tfile)
5194
5195         sleep 5
5196         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5197         atime1=$(stat -c %X $DIR/$tfile)
5198
5199         sleep 5
5200         cancel_lru_locks mdc
5201         cancel_lru_locks osc
5202         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5203         atime2=$(stat -c %X $DIR/$tfile)
5204
5205         do_facet $SINGLEMDS \
5206                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5207
5208         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5209         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5210 }
5211 run_test 39n "check that O_NOATIME is honored"
5212
5213 test_39o() {
5214         TESTDIR=$DIR/$tdir/$tfile
5215         [ -e $TESTDIR ] && rm -rf $TESTDIR
5216         mkdir -p $TESTDIR
5217         cd $TESTDIR
5218         links1=2
5219         ls
5220         mkdir a b
5221         ls
5222         links2=$(stat -c %h .)
5223         [ $(($links1 + 2)) != $links2 ] &&
5224                 error "wrong links count $(($links1 + 2)) != $links2"
5225         rmdir b
5226         links3=$(stat -c %h .)
5227         [ $(($links1 + 1)) != $links3 ] &&
5228                 error "wrong links count $links1 != $links3"
5229         return 0
5230 }
5231 run_test 39o "directory cached attributes updated after create"
5232
5233 test_39p() {
5234         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5235
5236         local MDTIDX=1
5237         TESTDIR=$DIR/$tdir/$tdir
5238         [ -e $TESTDIR ] && rm -rf $TESTDIR
5239         test_mkdir -p $TESTDIR
5240         cd $TESTDIR
5241         links1=2
5242         ls
5243         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5244         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5245         ls
5246         links2=$(stat -c %h .)
5247         [ $(($links1 + 2)) != $links2 ] &&
5248                 error "wrong links count $(($links1 + 2)) != $links2"
5249         rmdir remote_dir2
5250         links3=$(stat -c %h .)
5251         [ $(($links1 + 1)) != $links3 ] &&
5252                 error "wrong links count $links1 != $links3"
5253         return 0
5254 }
5255 run_test 39p "remote directory cached attributes updated after create ========"
5256
5257 test_39r() {
5258         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5259                 skip "no atime update on old OST"
5260         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5261                 skip_env "ldiskfs only test"
5262         fi
5263
5264         local saved_adiff
5265         saved_adiff=$(do_facet ost1 \
5266                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5267         stack_trap "do_facet ost1 \
5268                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5269
5270         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5271
5272         $LFS setstripe -i 0 $DIR/$tfile
5273         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5274                 error "can't write initial file"
5275         cancel_lru_locks osc
5276
5277         # exceed atime_diff and access file
5278         sleep 10
5279         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5280                 error "can't udpate atime"
5281
5282         local atime_cli=$(stat -c %X $DIR/$tfile)
5283         echo "client atime: $atime_cli"
5284         # allow atime update to be written to device
5285         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5286         sleep 5
5287
5288         local ostdev=$(ostdevname 1)
5289         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5290         local seq=${fid[3]#0x}
5291         local oid=${fid[1]}
5292         local oid_hex
5293
5294         if [ $seq == 0 ]; then
5295                 oid_hex=${fid[1]}
5296         else
5297                 oid_hex=${fid[2]#0x}
5298         fi
5299         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5300         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5301
5302         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5303         local atime_ost=$(do_facet ost1 "$cmd" |&
5304                           awk -F'[: ]' '/atime:/ { print $4 }')
5305         (( atime_cli == atime_ost )) ||
5306                 error "atime on client $atime_cli != ost $atime_ost"
5307 }
5308 run_test 39r "lazy atime update on OST"
5309
5310 test_39q() { # LU-8041
5311         local testdir=$DIR/$tdir
5312         mkdir -p $testdir
5313         multiop_bg_pause $testdir D_c || error "multiop failed"
5314         local multipid=$!
5315         cancel_lru_locks mdc
5316         kill -USR1 $multipid
5317         local atime=$(stat -c %X $testdir)
5318         [ "$atime" -ne 0 ] || error "atime is zero"
5319 }
5320 run_test 39q "close won't zero out atime"
5321
5322 test_39s() {
5323         local atime0
5324         local atime1
5325         local atime2
5326         local atime3
5327         local atime4
5328
5329         umount_client $MOUNT
5330         mount_client $MOUNT relatime
5331
5332         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5333         atime0=$(stat -c %X $DIR/$tfile)
5334
5335         # First read updates atime
5336         sleep 1
5337         cat $DIR/$tfile >/dev/null
5338         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5339
5340         # Next reads do not update atime
5341         sleep 1
5342         cat $DIR/$tfile >/dev/null
5343         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5344
5345         # If mtime is greater than atime, atime is updated
5346         sleep 1
5347         touch -m $DIR/$tfile # (mtime = now)
5348         sleep 1
5349         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5350         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5351
5352         # Next reads do not update atime
5353         sleep 1
5354         cat $DIR/$tfile >/dev/null
5355         atime4=$(stat -c %X $DIR/$tfile)
5356
5357         # Remount the client to clear 'relatime' option
5358         remount_client $MOUNT
5359
5360         (( atime0 < atime1 )) ||
5361                 error "atime $atime0 should be smaller than $atime1"
5362         (( atime1 == atime2 )) ||
5363                 error "atime $atime1 was updated to $atime2"
5364         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5365         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5366 }
5367 run_test 39s "relatime is supported"
5368
5369 test_40() {
5370         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5371         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5372                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5373         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5374                 error "$tfile is not 4096 bytes in size"
5375 }
5376 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5377
5378 test_41() {
5379         # bug 1553
5380         small_write $DIR/f41 18
5381 }
5382 run_test 41 "test small file write + fstat ====================="
5383
5384 count_ost_writes() {
5385         lctl get_param -n ${OSC}.*.stats |
5386                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5387                         END { printf("%0.0f", writes) }'
5388 }
5389
5390 # decent default
5391 WRITEBACK_SAVE=500
5392 DIRTY_RATIO_SAVE=40
5393 MAX_DIRTY_RATIO=50
5394 BG_DIRTY_RATIO_SAVE=10
5395 MAX_BG_DIRTY_RATIO=25
5396
5397 start_writeback() {
5398         trap 0
5399         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5400         # dirty_ratio, dirty_background_ratio
5401         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5402                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5403                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5404                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5405         else
5406                 # if file not here, we are a 2.4 kernel
5407                 kill -CONT `pidof kupdated`
5408         fi
5409 }
5410
5411 stop_writeback() {
5412         # setup the trap first, so someone cannot exit the test at the
5413         # exact wrong time and mess up a machine
5414         trap start_writeback EXIT
5415         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5416         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5417                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5418                 sysctl -w vm.dirty_writeback_centisecs=0
5419                 sysctl -w vm.dirty_writeback_centisecs=0
5420                 # save and increase /proc/sys/vm/dirty_ratio
5421                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5422                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5423                 # save and increase /proc/sys/vm/dirty_background_ratio
5424                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5425                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5426         else
5427                 # if file not here, we are a 2.4 kernel
5428                 kill -STOP `pidof kupdated`
5429         fi
5430 }
5431
5432 # ensure that all stripes have some grant before we test client-side cache
5433 setup_test42() {
5434         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5435                 dd if=/dev/zero of=$i bs=4k count=1
5436                 rm $i
5437         done
5438 }
5439
5440 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5441 # file truncation, and file removal.
5442 test_42a() {
5443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5444
5445         setup_test42
5446         cancel_lru_locks $OSC
5447         stop_writeback
5448         sync; sleep 1; sync # just to be safe
5449         BEFOREWRITES=`count_ost_writes`
5450         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5451         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5452         AFTERWRITES=`count_ost_writes`
5453         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5454                 error "$BEFOREWRITES < $AFTERWRITES"
5455         start_writeback
5456 }
5457 run_test 42a "ensure that we don't flush on close"
5458
5459 test_42b() {
5460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5461
5462         setup_test42
5463         cancel_lru_locks $OSC
5464         stop_writeback
5465         sync
5466         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5467         BEFOREWRITES=$(count_ost_writes)
5468         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5469         AFTERWRITES=$(count_ost_writes)
5470         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5471                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5472         fi
5473         BEFOREWRITES=$(count_ost_writes)
5474         sync || error "sync: $?"
5475         AFTERWRITES=$(count_ost_writes)
5476         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5477                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5478         fi
5479         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5480         start_writeback
5481         return 0
5482 }
5483 run_test 42b "test destroy of file with cached dirty data ======"
5484
5485 # if these tests just want to test the effect of truncation,
5486 # they have to be very careful.  consider:
5487 # - the first open gets a {0,EOF}PR lock
5488 # - the first write conflicts and gets a {0, count-1}PW
5489 # - the rest of the writes are under {count,EOF}PW
5490 # - the open for truncate tries to match a {0,EOF}PR
5491 #   for the filesize and cancels the PWs.
5492 # any number of fixes (don't get {0,EOF} on open, match
5493 # composite locks, do smarter file size management) fix
5494 # this, but for now we want these tests to verify that
5495 # the cancellation with truncate intent works, so we
5496 # start the file with a full-file pw lock to match against
5497 # until the truncate.
5498 trunc_test() {
5499         test=$1
5500         file=$DIR/$test
5501         offset=$2
5502         cancel_lru_locks $OSC
5503         stop_writeback
5504         # prime the file with 0,EOF PW to match
5505         touch $file
5506         $TRUNCATE $file 0
5507         sync; sync
5508         # now the real test..
5509         dd if=/dev/zero of=$file bs=1024 count=100
5510         BEFOREWRITES=`count_ost_writes`
5511         $TRUNCATE $file $offset
5512         cancel_lru_locks $OSC
5513         AFTERWRITES=`count_ost_writes`
5514         start_writeback
5515 }
5516
5517 test_42c() {
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         trunc_test 42c 1024
5521         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5522                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5523         rm $file
5524 }
5525 run_test 42c "test partial truncate of file with cached dirty data"
5526
5527 test_42d() {
5528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5529
5530         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5531         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5532         $LCTL set_param debug=+cache
5533
5534         trunc_test 42d 0
5535         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5536                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5537         rm $file
5538 }
5539 run_test 42d "test complete truncate of file with cached dirty data"
5540
5541 test_42e() { # bug22074
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543
5544         local TDIR=$DIR/${tdir}e
5545         local pages=16 # hardcoded 16 pages, don't change it.
5546         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5547         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5548         local max_dirty_mb
5549         local warmup_files
5550
5551         test_mkdir $DIR/${tdir}e
5552         $LFS setstripe -c 1 $TDIR
5553         createmany -o $TDIR/f $files
5554
5555         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5556
5557         # we assume that with $OSTCOUNT files, at least one of them will
5558         # be allocated on OST0.
5559         warmup_files=$((OSTCOUNT * max_dirty_mb))
5560         createmany -o $TDIR/w $warmup_files
5561
5562         # write a large amount of data into one file and sync, to get good
5563         # avail_grant number from OST.
5564         for ((i=0; i<$warmup_files; i++)); do
5565                 idx=$($LFS getstripe -i $TDIR/w$i)
5566                 [ $idx -ne 0 ] && continue
5567                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5568                 break
5569         done
5570         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5571         sync
5572         $LCTL get_param $proc_osc0/cur_dirty_bytes
5573         $LCTL get_param $proc_osc0/cur_grant_bytes
5574
5575         # create as much dirty pages as we can while not to trigger the actual
5576         # RPCs directly. but depends on the env, VFS may trigger flush during this
5577         # period, hopefully we are good.
5578         for ((i=0; i<$warmup_files; i++)); do
5579                 idx=$($LFS getstripe -i $TDIR/w$i)
5580                 [ $idx -ne 0 ] && continue
5581                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5582         done
5583         $LCTL get_param $proc_osc0/cur_dirty_bytes
5584         $LCTL get_param $proc_osc0/cur_grant_bytes
5585
5586         # perform the real test
5587         $LCTL set_param $proc_osc0/rpc_stats 0
5588         for ((;i<$files; i++)); do
5589                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5590                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5591         done
5592         sync
5593         $LCTL get_param $proc_osc0/rpc_stats
5594
5595         local percent=0
5596         local have_ppr=false
5597         $LCTL get_param $proc_osc0/rpc_stats |
5598                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5599                         # skip lines until we are at the RPC histogram data
5600                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5601                         $have_ppr || continue
5602
5603                         # we only want the percent stat for < 16 pages
5604                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5605
5606                         percent=$((percent + WPCT))
5607                         if [[ $percent -gt 15 ]]; then
5608                                 error "less than 16-pages write RPCs" \
5609                                       "$percent% > 15%"
5610                                 break
5611                         fi
5612                 done
5613         rm -rf $TDIR
5614 }
5615 run_test 42e "verify sub-RPC writes are not done synchronously"
5616
5617 test_43A() { # was test_43
5618         test_mkdir $DIR/$tdir
5619         cp -p /bin/ls $DIR/$tdir/$tfile
5620         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5621         pid=$!
5622         # give multiop a chance to open
5623         sleep 1
5624
5625         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5626         kill -USR1 $pid
5627         # Wait for multiop to exit
5628         wait $pid
5629 }
5630 run_test 43A "execution of file opened for write should return -ETXTBSY"
5631
5632 test_43a() {
5633         test_mkdir $DIR/$tdir
5634         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5635         $DIR/$tdir/sleep 60 &
5636         SLEEP_PID=$!
5637         # Make sure exec of $tdir/sleep wins race with truncate
5638         sleep 1
5639         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5640         kill $SLEEP_PID
5641 }
5642 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5643
5644 test_43b() {
5645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5646
5647         test_mkdir $DIR/$tdir
5648         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5649         $DIR/$tdir/sleep 60 &
5650         SLEEP_PID=$!
5651         # Make sure exec of $tdir/sleep wins race with truncate
5652         sleep 1
5653         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5654         kill $SLEEP_PID
5655 }
5656 run_test 43b "truncate of file being executed should return -ETXTBSY"
5657
5658 test_43c() {
5659         local testdir="$DIR/$tdir"
5660         test_mkdir $testdir
5661         cp $SHELL $testdir/
5662         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5663                 ( cd $testdir && md5sum -c )
5664 }
5665 run_test 43c "md5sum of copy into lustre"
5666
5667 test_44A() { # was test_44
5668         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5669
5670         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5671         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5672 }
5673 run_test 44A "zero length read from a sparse stripe"
5674
5675 test_44a() {
5676         local nstripe=$($LFS getstripe -c -d $DIR)
5677         [ -z "$nstripe" ] && skip "can't get stripe info"
5678         [[ $nstripe -gt $OSTCOUNT ]] &&
5679                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5680
5681         local stride=$($LFS getstripe -S -d $DIR)
5682         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5683                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5684         fi
5685
5686         OFFSETS="0 $((stride/2)) $((stride-1))"
5687         for offset in $OFFSETS; do
5688                 for i in $(seq 0 $((nstripe-1))); do
5689                         local GLOBALOFFSETS=""
5690                         # size in Bytes
5691                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5692                         local myfn=$DIR/d44a-$size
5693                         echo "--------writing $myfn at $size"
5694                         ll_sparseness_write $myfn $size ||
5695                                 error "ll_sparseness_write"
5696                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5697                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5698                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5699
5700                         for j in $(seq 0 $((nstripe-1))); do
5701                                 # size in Bytes
5702                                 size=$((((j + $nstripe )*$stride + $offset)))
5703                                 ll_sparseness_write $myfn $size ||
5704                                         error "ll_sparseness_write"
5705                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5706                         done
5707                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5708                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5709                         rm -f $myfn
5710                 done
5711         done
5712 }
5713 run_test 44a "test sparse pwrite ==============================="
5714
5715 dirty_osc_total() {
5716         tot=0
5717         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5718                 tot=$(($tot + $d))
5719         done
5720         echo $tot
5721 }
5722 do_dirty_record() {
5723         before=`dirty_osc_total`
5724         echo executing "\"$*\""
5725         eval $*
5726         after=`dirty_osc_total`
5727         echo before $before, after $after
5728 }
5729 test_45() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731
5732         f="$DIR/f45"
5733         # Obtain grants from OST if it supports it
5734         echo blah > ${f}_grant
5735         stop_writeback
5736         sync
5737         do_dirty_record "echo blah > $f"
5738         [[ $before -eq $after ]] && error "write wasn't cached"
5739         do_dirty_record "> $f"
5740         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5741         do_dirty_record "echo blah > $f"
5742         [[ $before -eq $after ]] && error "write wasn't cached"
5743         do_dirty_record "sync"
5744         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5745         do_dirty_record "echo blah > $f"
5746         [[ $before -eq $after ]] && error "write wasn't cached"
5747         do_dirty_record "cancel_lru_locks osc"
5748         [[ $before -gt $after ]] ||
5749                 error "lock cancellation didn't lower dirty count"
5750         start_writeback
5751 }
5752 run_test 45 "osc io page accounting ============================"
5753
5754 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5755 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5756 # objects offset and an assert hit when an rpc was built with 1023's mapped
5757 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5758 test_46() {
5759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5760
5761         f="$DIR/f46"
5762         stop_writeback
5763         sync
5764         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5765         sync
5766         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5767         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5768         sync
5769         start_writeback
5770 }
5771 run_test 46 "dirtying a previously written page ================"
5772
5773 # test_47 is removed "Device nodes check" is moved to test_28
5774
5775 test_48a() { # bug 2399
5776         [ "$mds1_FSTYPE" = "zfs" ] &&
5777         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5778                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5779
5780         test_mkdir $DIR/$tdir
5781         cd $DIR/$tdir
5782         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5783         test_mkdir $DIR/$tdir
5784         touch foo || error "'touch foo' failed after recreating cwd"
5785         test_mkdir bar
5786         touch .foo || error "'touch .foo' failed after recreating cwd"
5787         test_mkdir .bar
5788         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5789         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5790         cd . || error "'cd .' failed after recreating cwd"
5791         mkdir . && error "'mkdir .' worked after recreating cwd"
5792         rmdir . && error "'rmdir .' worked after recreating cwd"
5793         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5794         cd .. || error "'cd ..' failed after recreating cwd"
5795 }
5796 run_test 48a "Access renamed working dir (should return errors)="
5797
5798 test_48b() { # bug 2399
5799         rm -rf $DIR/$tdir
5800         test_mkdir $DIR/$tdir
5801         cd $DIR/$tdir
5802         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5803         touch foo && error "'touch foo' worked after removing cwd"
5804         mkdir foo && error "'mkdir foo' worked after removing cwd"
5805         touch .foo && error "'touch .foo' worked after removing cwd"
5806         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5807         ls . > /dev/null && error "'ls .' worked after removing cwd"
5808         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5809         mkdir . && error "'mkdir .' worked after removing cwd"
5810         rmdir . && error "'rmdir .' worked after removing cwd"
5811         ln -s . foo && error "'ln -s .' worked after removing cwd"
5812         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5813 }
5814 run_test 48b "Access removed working dir (should return errors)="
5815
5816 test_48c() { # bug 2350
5817         #lctl set_param debug=-1
5818         #set -vx
5819         rm -rf $DIR/$tdir
5820         test_mkdir -p $DIR/$tdir/dir
5821         cd $DIR/$tdir/dir
5822         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5823         $TRACE touch foo && error "touch foo worked after removing cwd"
5824         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5825         touch .foo && error "touch .foo worked after removing cwd"
5826         mkdir .foo && error "mkdir .foo worked after removing cwd"
5827         $TRACE ls . && error "'ls .' worked after removing cwd"
5828         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5829         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5830         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5831         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5832         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5833 }
5834 run_test 48c "Access removed working subdir (should return errors)"
5835
5836 test_48d() { # bug 2350
5837         #lctl set_param debug=-1
5838         #set -vx
5839         rm -rf $DIR/$tdir
5840         test_mkdir -p $DIR/$tdir/dir
5841         cd $DIR/$tdir/dir
5842         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5843         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5844         $TRACE touch foo && error "'touch foo' worked after removing parent"
5845         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5846         touch .foo && error "'touch .foo' worked after removing parent"
5847         mkdir .foo && error "mkdir .foo worked after removing parent"
5848         $TRACE ls . && error "'ls .' worked after removing parent"
5849         $TRACE ls .. && error "'ls ..' worked after removing parent"
5850         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5851         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5852         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5853         true
5854 }
5855 run_test 48d "Access removed parent subdir (should return errors)"
5856
5857 test_48e() { # bug 4134
5858         #lctl set_param debug=-1
5859         #set -vx
5860         rm -rf $DIR/$tdir
5861         test_mkdir -p $DIR/$tdir/dir
5862         cd $DIR/$tdir/dir
5863         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5864         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5865         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5866         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5867         # On a buggy kernel addition of "touch foo" after cd .. will
5868         # produce kernel oops in lookup_hash_it
5869         touch ../foo && error "'cd ..' worked after recreate parent"
5870         cd $DIR
5871         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5872 }
5873 run_test 48e "Access to recreated parent subdir (should return errors)"
5874
5875 test_48f() {
5876         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5877                 skip "need MDS >= 2.13.55"
5878         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5879         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5880                 skip "needs different host for mdt1 mdt2"
5881         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5882
5883         $LFS mkdir -i0 $DIR/$tdir
5884         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5885
5886         for d in sub1 sub2 sub3; do
5887                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5888                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5889                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5890         done
5891
5892         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5893 }
5894 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5895
5896 test_49() { # LU-1030
5897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5898         remote_ost_nodsh && skip "remote OST with nodsh"
5899
5900         # get ost1 size - $FSNAME-OST0000
5901         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5902                 awk '{ print $4 }')
5903         # write 800M at maximum
5904         [[ $ost1_size -lt 2 ]] && ost1_size=2
5905         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5906
5907         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5908         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5909         local dd_pid=$!
5910
5911         # change max_pages_per_rpc while writing the file
5912         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5913         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5914         # loop until dd process exits
5915         while ps ax -opid | grep -wq $dd_pid; do
5916                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5917                 sleep $((RANDOM % 5 + 1))
5918         done
5919         # restore original max_pages_per_rpc
5920         $LCTL set_param $osc1_mppc=$orig_mppc
5921         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5922 }
5923 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5924
5925 test_50() {
5926         # bug 1485
5927         test_mkdir $DIR/$tdir
5928         cd $DIR/$tdir
5929         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5930 }
5931 run_test 50 "special situations: /proc symlinks  ==============="
5932
5933 test_51a() {    # was test_51
5934         # bug 1516 - create an empty entry right after ".." then split dir
5935         test_mkdir -c1 $DIR/$tdir
5936         touch $DIR/$tdir/foo
5937         $MCREATE $DIR/$tdir/bar
5938         rm $DIR/$tdir/foo
5939         createmany -m $DIR/$tdir/longfile 201
5940         FNUM=202
5941         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5942                 $MCREATE $DIR/$tdir/longfile$FNUM
5943                 FNUM=$(($FNUM + 1))
5944                 echo -n "+"
5945         done
5946         echo
5947         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5948 }
5949 run_test 51a "special situations: split htree with empty entry =="
5950
5951 cleanup_print_lfs_df () {
5952         trap 0
5953         $LFS df
5954         $LFS df -i
5955 }
5956
5957 test_51b() {
5958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5959
5960         local dir=$DIR/$tdir
5961         local nrdirs=$((65536 + 100))
5962
5963         # cleanup the directory
5964         rm -fr $dir
5965
5966         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5967
5968         $LFS df
5969         $LFS df -i
5970         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5971         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5972         [[ $numfree -lt $nrdirs ]] &&
5973                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5974
5975         # need to check free space for the directories as well
5976         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5977         numfree=$(( blkfree / $(fs_inode_ksize) ))
5978         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5979
5980         trap cleanup_print_lfs_df EXIT
5981
5982         # create files
5983         createmany -d $dir/d $nrdirs || {
5984                 unlinkmany $dir/d $nrdirs
5985                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5986         }
5987
5988         # really created :
5989         nrdirs=$(ls -U $dir | wc -l)
5990
5991         # unlink all but 100 subdirectories, then check it still works
5992         local left=100
5993         local delete=$((nrdirs - left))
5994
5995         $LFS df
5996         $LFS df -i
5997
5998         # for ldiskfs the nlink count should be 1, but this is OSD specific
5999         # and so this is listed for informational purposes only
6000         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6001         unlinkmany -d $dir/d $delete ||
6002                 error "unlink of first $delete subdirs failed"
6003
6004         echo "nlink between: $(stat -c %h $dir)"
6005         local found=$(ls -U $dir | wc -l)
6006         [ $found -ne $left ] &&
6007                 error "can't find subdirs: found only $found, expected $left"
6008
6009         unlinkmany -d $dir/d $delete $left ||
6010                 error "unlink of second $left subdirs failed"
6011         # regardless of whether the backing filesystem tracks nlink accurately
6012         # or not, the nlink count shouldn't be more than "." and ".." here
6013         local after=$(stat -c %h $dir)
6014         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6015                 echo "nlink after: $after"
6016
6017         cleanup_print_lfs_df
6018 }
6019 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6020
6021 test_51d_sub() {
6022         local stripecount=$1
6023         local nfiles=$2
6024
6025         log "create files with stripecount=$stripecount"
6026         $LFS setstripe -C $stripecount $DIR/$tdir
6027         createmany -o $DIR/$tdir/t- $nfiles
6028         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6029         for ((n = 0; n < $OSTCOUNT; n++)); do
6030                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6031                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6032                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6033                             '($1 == '$n') { objs += 1 } \
6034                             END { printf("%0.0f", objs) }')
6035                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6036         done
6037         unlinkmany $DIR/$tdir/t- $nfiles
6038         rm  -f $TMP/$tfile
6039
6040         local nlast
6041         local min=4
6042         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6043
6044         # For some combinations of stripecount and OSTCOUNT current code
6045         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6046         # than others. Rather than skipping this test entirely, check that
6047         # and keep testing to ensure imbalance does not get worse. LU-15282
6048         (( (OSTCOUNT == 6 && stripecount == 4) ||
6049            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6050            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6051         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6052                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6053                         { $LFS df && $LFS df -i &&
6054                         error "stripecount=$stripecount: " \
6055                               "OST $n has fewer objects vs. OST $nlast " \
6056                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6057                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6058                         { $LFS df && $LFS df -i &&
6059                         error "stripecount=$stripecount: " \
6060                               "OST $n has more objects vs. OST $nlast " \
6061                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6062
6063                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6064                         { $LFS df && $LFS df -i &&
6065                         error "stripecount=$stripecount: " \
6066                               "OST $n has fewer #0 objects vs. OST $nlast " \
6067                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6068                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6069                         { $LFS df && $LFS df -i &&
6070                         error "stripecount=$stripecount: " \
6071                               "OST $n has more #0 objects vs. OST $nlast " \
6072                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6073         done
6074 }
6075
6076 test_51d() {
6077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6078         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6079
6080         local stripecount
6081         local per_ost=100
6082         local nfiles=$((per_ost * OSTCOUNT))
6083         local mdts=$(comma_list $(mdts_nodes))
6084         local param="osp.*.create_count"
6085         local qos_old=$(do_facet mds1 \
6086                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6087
6088         do_nodes $mdts \
6089                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6090         stack_trap "do_nodes $mdts \
6091                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6092
6093         test_mkdir $DIR/$tdir
6094         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6095         (( dirstripes > 0 )) || dirstripes=1
6096
6097         # Ensure enough OST objects precreated for tests to pass without
6098         # running out of objects.  This is an LOV r-r OST algorithm test,
6099         # not an OST object precreation test.
6100         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6101         (( old >= nfiles )) ||
6102         {
6103                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6104
6105                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6106                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6107
6108                 # trigger precreation from all MDTs for all OSTs
6109                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6110                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6111                 done
6112         }
6113
6114         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6115                 sleep 8  # allow object precreation to catch up
6116                 test_51d_sub $stripecount $nfiles
6117         done
6118 }
6119 run_test 51d "check LOV round-robin OST object distribution"
6120
6121 test_51e() {
6122         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6123                 skip_env "ldiskfs only test"
6124         fi
6125
6126         test_mkdir -c1 $DIR/$tdir
6127         test_mkdir -c1 $DIR/$tdir/d0
6128
6129         touch $DIR/$tdir/d0/foo
6130         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6131                 error "file exceed 65000 nlink limit!"
6132         unlinkmany $DIR/$tdir/d0/f- 65001
6133         return 0
6134 }
6135 run_test 51e "check file nlink limit"
6136
6137 test_51f() {
6138         test_mkdir $DIR/$tdir
6139
6140         local max=100000
6141         local ulimit_old=$(ulimit -n)
6142         local spare=20 # number of spare fd's for scripts/libraries, etc.
6143         local mdt=$($LFS getstripe -m $DIR/$tdir)
6144         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6145
6146         echo "MDT$mdt numfree=$numfree, max=$max"
6147         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6148         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6149                 while ! ulimit -n $((numfree + spare)); do
6150                         numfree=$((numfree * 3 / 4))
6151                 done
6152                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6153         else
6154                 echo "left ulimit at $ulimit_old"
6155         fi
6156
6157         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6158                 unlinkmany $DIR/$tdir/f $numfree
6159                 error "create+open $numfree files in $DIR/$tdir failed"
6160         }
6161         ulimit -n $ulimit_old
6162
6163         # if createmany exits at 120s there will be fewer than $numfree files
6164         unlinkmany $DIR/$tdir/f $numfree || true
6165 }
6166 run_test 51f "check many open files limit"
6167
6168 test_52a() {
6169         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6170         test_mkdir $DIR/$tdir
6171         touch $DIR/$tdir/foo
6172         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6173         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6174         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6175         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6176         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6177                                         error "link worked"
6178         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6179         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6180         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6181                                                      error "lsattr"
6182         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6183         cp -r $DIR/$tdir $TMP/
6184         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6185 }
6186 run_test 52a "append-only flag test (should return errors)"
6187
6188 test_52b() {
6189         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6190         test_mkdir $DIR/$tdir
6191         touch $DIR/$tdir/foo
6192         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6193         cat test > $DIR/$tdir/foo && error "cat test worked"
6194         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6195         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6196         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6197                                         error "link worked"
6198         echo foo >> $DIR/$tdir/foo && error "echo worked"
6199         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6200         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6201         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6202         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6203                                                         error "lsattr"
6204         chattr -i $DIR/$tdir/foo || error "chattr failed"
6205
6206         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6207 }
6208 run_test 52b "immutable flag test (should return errors) ======="
6209
6210 test_53() {
6211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6212         remote_mds_nodsh && skip "remote MDS with nodsh"
6213         remote_ost_nodsh && skip "remote OST with nodsh"
6214
6215         local param
6216         local param_seq
6217         local ostname
6218         local mds_last
6219         local mds_last_seq
6220         local ost_last
6221         local ost_last_seq
6222         local ost_last_id
6223         local ostnum
6224         local node
6225         local found=false
6226         local support_last_seq=true
6227
6228         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6229                 support_last_seq=false
6230
6231         # only test MDT0000
6232         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6233         local value
6234         for value in $(do_facet $SINGLEMDS \
6235                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6236                 param=$(echo ${value[0]} | cut -d "=" -f1)
6237                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6238
6239                 if $support_last_seq; then
6240                         param_seq=$(echo $param |
6241                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6242                         mds_last_seq=$(do_facet $SINGLEMDS \
6243                                        $LCTL get_param -n $param_seq)
6244                 fi
6245                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6246
6247                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6248                 node=$(facet_active_host ost$((ostnum+1)))
6249                 param="obdfilter.$ostname.last_id"
6250                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6251                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6252                         ost_last_id=$ost_last
6253
6254                         if $support_last_seq; then
6255                                 ost_last_id=$(echo $ost_last |
6256                                               awk -F':' '{print $2}' |
6257                                               sed -e "s/^0x//g")
6258                                 ost_last_seq=$(echo $ost_last |
6259                                                awk -F':' '{print $1}')
6260                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6261                         fi
6262
6263                         if [[ $ost_last_id != $mds_last ]]; then
6264                                 error "$ost_last_id != $mds_last"
6265                         else
6266                                 found=true
6267                                 break
6268                         fi
6269                 done
6270         done
6271         $found || error "can not match last_seq/last_id for $mdtosc"
6272         return 0
6273 }
6274 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6275
6276 test_54a() {
6277         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6278
6279         LANG=C $SOCKETSERVER $DIR/socket ||
6280                 error "$SOCKETSERVER $DIR/socket failed: $?"
6281         LANG=C $SOCKETCLIENT $DIR/socket ||
6282                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6283         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6284 }
6285 run_test 54a "unix domain socket test =========================="
6286
6287 test_54b() {
6288         f="$DIR/f54b"
6289         mknod $f c 1 3
6290         chmod 0666 $f
6291         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6292 }
6293 run_test 54b "char device works in lustre ======================"
6294
6295 find_loop_dev() {
6296         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6297         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6298         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6299
6300         for i in $(seq 3 7); do
6301                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6302                 LOOPDEV=$LOOPBASE$i
6303                 LOOPNUM=$i
6304                 break
6305         done
6306 }
6307
6308 cleanup_54c() {
6309         local rc=0
6310         loopdev="$DIR/loop54c"
6311
6312         trap 0
6313         $UMOUNT $DIR/$tdir || rc=$?
6314         losetup -d $loopdev || true
6315         losetup -d $LOOPDEV || true
6316         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6317         return $rc
6318 }
6319
6320 test_54c() {
6321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6322
6323         loopdev="$DIR/loop54c"
6324
6325         find_loop_dev
6326         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6327         trap cleanup_54c EXIT
6328         mknod $loopdev b 7 $LOOPNUM
6329         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6330         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6331         losetup $loopdev $DIR/$tfile ||
6332                 error "can't set up $loopdev for $DIR/$tfile"
6333         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6334         test_mkdir $DIR/$tdir
6335         mount -t ext2 $loopdev $DIR/$tdir ||
6336                 error "error mounting $loopdev on $DIR/$tdir"
6337         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6338                 error "dd write"
6339         df $DIR/$tdir
6340         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6341                 error "dd read"
6342         cleanup_54c
6343 }
6344 run_test 54c "block device works in lustre ====================="
6345
6346 test_54d() {
6347         local pipe="$DIR/$tfile.pipe"
6348         local string="aaaaaa"
6349
6350         mknod $pipe p
6351         echo -n "$string" > $pipe &
6352         local result=$(cat $pipe)
6353         [[ "$result" == "$string" ]] || error "$result != $string"
6354 }
6355 run_test 54d "fifo device works in lustre ======================"
6356
6357 test_54e() {
6358         f="$DIR/f54e"
6359         string="aaaaaa"
6360         cp -aL /dev/console $f
6361         echo $string > $f || error "echo $string to $f failed"
6362 }
6363 run_test 54e "console/tty device works in lustre ======================"
6364
6365 test_55a() {
6366         local dev_path="/sys/kernel/debug/lustre/devices"
6367
6368         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6369
6370         # This must be run in iteractive mode, since attach and setup
6371         # are stateful
6372         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6373                 attach obd_test obd_name obd_uuid
6374                 setup obd_test
6375         EOF"
6376
6377         echo "Devices:"
6378         cat "$dev_path" | tail -n 10
6379
6380         $LCTL --device "obd_name" cleanup
6381         $LCTL --device "obd_name" detach
6382
6383         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6384                 error "OBD unit test failed"
6385
6386         rmmod -v obd_test ||
6387                 error "rmmod failed (may trigger a failure in a later test)"
6388 }
6389 run_test 55a "OBD device life cycle unit tests"
6390
6391 test_55b() {
6392         local dev_path="/sys/kernel/debug/lustre/devices"
6393         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6394
6395         # Set up a large number of devices, using the number
6396         # that can be set up in about a minute (based on prior
6397         # testing). We don't want to run this test forever.
6398         local num_dev_to_create="$(( 24000 - $dev_count))"
6399
6400         load_module obdclass/obd_test || error "load_module failed"
6401
6402         local start=$SECONDS
6403
6404         # This must be run in iteractive mode, since attach and setup
6405         # are stateful
6406         for ((i = 1; i <= num_dev_to_create; i++)); do
6407                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6408                 echo "setup obd_test_$i"
6409         done | $LCTL || error "OBD device creation failed"
6410
6411         echo "Load time: $((SECONDS - start))"
6412         echo "Devices:"
6413         cat "$dev_path" | tail -n 10
6414
6415         for ((i = 1; i <= num_dev_to_create; i++)); do
6416                 echo "--device obd_name_$i cleanup"
6417                 echo "--device obd_name_$i detach"
6418         done | $LCTL || error "OBD device cleanup failed"
6419
6420         echo "Unload time: $((SECONDS - start))"
6421
6422         rmmod -v obd_test ||
6423                 error "rmmod failed (may trigger a failure in a later test)"
6424 }
6425 run_test 55b "Load and unload max OBD devices"
6426
6427 test_56a() {
6428         local numfiles=3
6429         local numdirs=2
6430         local dir=$DIR/$tdir
6431
6432         rm -rf $dir
6433         test_mkdir -p $dir/dir
6434         for i in $(seq $numfiles); do
6435                 touch $dir/file$i
6436                 touch $dir/dir/file$i
6437         done
6438
6439         local numcomp=$($LFS getstripe --component-count $dir)
6440
6441         [[ $numcomp == 0 ]] && numcomp=1
6442
6443         # test lfs getstripe with --recursive
6444         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6445
6446         [[ $filenum -eq $((numfiles * 2)) ]] ||
6447                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6448         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6449         [[ $filenum -eq $numfiles ]] ||
6450                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6451         echo "$LFS getstripe showed obdidx or l_ost_idx"
6452
6453         # test lfs getstripe with file instead of dir
6454         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6455         [[ $filenum -eq 1 ]] ||
6456                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6457         echo "$LFS getstripe file1 passed"
6458
6459         #test lfs getstripe with --verbose
6460         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6461         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6462                 error "$LFS getstripe --verbose $dir: "\
6463                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6464         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6465                 error "$LFS getstripe $dir: showed lmm_magic"
6466
6467         #test lfs getstripe with -v prints lmm_fid
6468         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6469         local countfids=$((numdirs + numfiles * numcomp))
6470         [[ $filenum -eq $countfids ]] ||
6471                 error "$LFS getstripe -v $dir: "\
6472                       "got $filenum want $countfids lmm_fid"
6473         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6474                 error "$LFS getstripe $dir: showed lmm_fid by default"
6475         echo "$LFS getstripe --verbose passed"
6476
6477         #check for FID information
6478         local fid1=$($LFS getstripe --fid $dir/file1)
6479         local fid2=$($LFS getstripe --verbose $dir/file1 |
6480                      awk '/lmm_fid: / { print $2; exit; }')
6481         local fid3=$($LFS path2fid $dir/file1)
6482
6483         [ "$fid1" != "$fid2" ] &&
6484                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6485         [ "$fid1" != "$fid3" ] &&
6486                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6487         echo "$LFS getstripe --fid passed"
6488
6489         #test lfs getstripe with --obd
6490         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6491                 error "$LFS getstripe --obd wrong_uuid: should return error"
6492
6493         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6494
6495         local ostidx=1
6496         local obduuid=$(ostuuid_from_index $ostidx)
6497         local found=$($LFS getstripe -r --obd $obduuid $dir |
6498                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6499
6500         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6501         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6502                 ((filenum--))
6503         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6504                 ((filenum--))
6505
6506         [[ $found -eq $filenum ]] ||
6507                 error "$LFS getstripe --obd: found $found expect $filenum"
6508         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6509                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6510                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6511                 error "$LFS getstripe --obd: should not show file on other obd"
6512         echo "$LFS getstripe --obd passed"
6513 }
6514 run_test 56a "check $LFS getstripe"
6515
6516 test_56b() {
6517         local dir=$DIR/$tdir
6518         local numdirs=3
6519
6520         test_mkdir $dir
6521         for i in $(seq $numdirs); do
6522                 test_mkdir $dir/dir$i
6523         done
6524
6525         # test lfs getdirstripe default mode is non-recursion, which is
6526         # different from lfs getstripe
6527         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6528
6529         [[ $dircnt -eq 1 ]] ||
6530                 error "$LFS getdirstripe: found $dircnt, not 1"
6531         dircnt=$($LFS getdirstripe --recursive $dir |
6532                 grep -c lmv_stripe_count)
6533         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6534                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6535 }
6536 run_test 56b "check $LFS getdirstripe"
6537
6538 test_56bb() {
6539         verify_yaml_available || skip_env "YAML verification not installed"
6540         local output_file=$DIR/$tfile.out
6541
6542         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6543
6544         cat $output_file
6545         cat $output_file | verify_yaml || error "layout is not valid YAML"
6546 }
6547 run_test 56bb "check $LFS getdirstripe layout is YAML"
6548
6549 test_56c() {
6550         remote_ost_nodsh && skip "remote OST with nodsh"
6551
6552         local ost_idx=0
6553         local ost_name=$(ostname_from_index $ost_idx)
6554         local old_status=$(ost_dev_status $ost_idx)
6555         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6556
6557         [[ -z "$old_status" ]] ||
6558                 skip_env "OST $ost_name is in $old_status status"
6559
6560         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6561         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6562                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6563         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6564                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6565                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6566         fi
6567
6568         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6569                 error "$LFS df -v showing inactive devices"
6570         sleep_maxage
6571
6572         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6573
6574         [[ "$new_status" =~ "D" ]] ||
6575                 error "$ost_name status is '$new_status', missing 'D'"
6576         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6577                 [[ "$new_status" =~ "N" ]] ||
6578                         error "$ost_name status is '$new_status', missing 'N'"
6579         fi
6580         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6581                 [[ "$new_status" =~ "f" ]] ||
6582                         error "$ost_name status is '$new_status', missing 'f'"
6583         fi
6584
6585         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6586         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6587                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6588         [[ -z "$p" ]] && restore_lustre_params < $p || true
6589         sleep_maxage
6590
6591         new_status=$(ost_dev_status $ost_idx)
6592         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6593                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6594         # can't check 'f' as devices may actually be on flash
6595 }
6596 run_test 56c "check 'lfs df' showing device status"
6597
6598 test_56d() {
6599         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6600         local osts=$($LFS df -v $MOUNT | grep -c OST)
6601
6602         $LFS df $MOUNT
6603
6604         (( mdts == MDSCOUNT )) ||
6605                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6606         (( osts == OSTCOUNT )) ||
6607                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6608 }
6609 run_test 56d "'lfs df -v' prints only configured devices"
6610
6611 test_56e() {
6612         err_enoent=2 # No such file or directory
6613         err_eopnotsupp=95 # Operation not supported
6614
6615         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6616         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6617
6618         # Check for handling of path not exists
6619         output=$($LFS df $enoent_mnt 2>&1)
6620         ret=$?
6621
6622         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6623         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6624                 error "expect failure $err_enoent, not $ret"
6625
6626         # Check for handling of non-Lustre FS
6627         output=$($LFS df $notsup_mnt)
6628         ret=$?
6629
6630         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6631         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6632                 error "expect success $err_eopnotsupp, not $ret"
6633
6634         # Check for multiple LustreFS argument
6635         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6636         ret=$?
6637
6638         [[ $output -eq 3 && $ret -eq 0 ]] ||
6639                 error "expect success 3, not $output, rc = $ret"
6640
6641         # Check for correct non-Lustre FS handling among multiple
6642         # LustreFS argument
6643         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6644                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6645         ret=$?
6646
6647         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6648                 error "expect success 2, not $output, rc = $ret"
6649 }
6650 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6651
6652 NUMFILES=3
6653 NUMDIRS=3
6654 setup_56() {
6655         local local_tdir="$1"
6656         local local_numfiles="$2"
6657         local local_numdirs="$3"
6658         local dir_params="$4"
6659         local dir_stripe_params="$5"
6660
6661         if [ ! -d "$local_tdir" ] ; then
6662                 test_mkdir -p $dir_stripe_params $local_tdir
6663                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6664                 for i in $(seq $local_numfiles) ; do
6665                         touch $local_tdir/file$i
6666                 done
6667                 for i in $(seq $local_numdirs) ; do
6668                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6669                         for j in $(seq $local_numfiles) ; do
6670                                 touch $local_tdir/dir$i/file$j
6671                         done
6672                 done
6673         fi
6674 }
6675
6676 setup_56_special() {
6677         local local_tdir=$1
6678         local local_numfiles=$2
6679         local local_numdirs=$3
6680
6681         setup_56 $local_tdir $local_numfiles $local_numdirs
6682
6683         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6684                 for i in $(seq $local_numfiles) ; do
6685                         mknod $local_tdir/loop${i}b b 7 $i
6686                         mknod $local_tdir/null${i}c c 1 3
6687                         ln -s $local_tdir/file1 $local_tdir/link${i}
6688                 done
6689                 for i in $(seq $local_numdirs) ; do
6690                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6691                         mknod $local_tdir/dir$i/null${i}c c 1 3
6692                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6693                 done
6694         fi
6695 }
6696
6697 test_56g() {
6698         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6699         local expected=$(($NUMDIRS + 2))
6700
6701         setup_56 $dir $NUMFILES $NUMDIRS
6702
6703         # test lfs find with -name
6704         for i in $(seq $NUMFILES) ; do
6705                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6706
6707                 [ $nums -eq $expected ] ||
6708                         error "lfs find -name '*$i' $dir wrong: "\
6709                               "found $nums, expected $expected"
6710         done
6711 }
6712 run_test 56g "check lfs find -name"
6713
6714 test_56h() {
6715         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6716         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6717
6718         setup_56 $dir $NUMFILES $NUMDIRS
6719
6720         # test lfs find with ! -name
6721         for i in $(seq $NUMFILES) ; do
6722                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6723
6724                 [ $nums -eq $expected ] ||
6725                         error "lfs find ! -name '*$i' $dir wrong: "\
6726                               "found $nums, expected $expected"
6727         done
6728 }
6729 run_test 56h "check lfs find ! -name"
6730
6731 test_56i() {
6732         local dir=$DIR/$tdir
6733
6734         test_mkdir $dir
6735
6736         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6737         local out=$($cmd)
6738
6739         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6740 }
6741 run_test 56i "check 'lfs find -ost UUID' skips directories"
6742
6743 test_56j() {
6744         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6745
6746         setup_56_special $dir $NUMFILES $NUMDIRS
6747
6748         local expected=$((NUMDIRS + 1))
6749         local cmd="$LFS find -type d $dir"
6750         local nums=$($cmd | wc -l)
6751
6752         [ $nums -eq $expected ] ||
6753                 error "'$cmd' wrong: found $nums, expected $expected"
6754 }
6755 run_test 56j "check lfs find -type d"
6756
6757 test_56k() {
6758         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6759
6760         setup_56_special $dir $NUMFILES $NUMDIRS
6761
6762         local expected=$(((NUMDIRS + 1) * NUMFILES))
6763         local cmd="$LFS find -type f $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768 }
6769 run_test 56k "check lfs find -type f"
6770
6771 test_56l() {
6772         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6773
6774         setup_56_special $dir $NUMFILES $NUMDIRS
6775
6776         local expected=$((NUMDIRS + NUMFILES))
6777         local cmd="$LFS find -type b $dir"
6778         local nums=$($cmd | wc -l)
6779
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782 }
6783 run_test 56l "check lfs find -type b"
6784
6785 test_56m() {
6786         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6787
6788         setup_56_special $dir $NUMFILES $NUMDIRS
6789
6790         local expected=$((NUMDIRS + NUMFILES))
6791         local cmd="$LFS find -type c $dir"
6792         local nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795 }
6796 run_test 56m "check lfs find -type c"
6797
6798 test_56n() {
6799         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6800         setup_56_special $dir $NUMFILES $NUMDIRS
6801
6802         local expected=$((NUMDIRS + NUMFILES))
6803         local cmd="$LFS find -type l $dir"
6804         local nums=$($cmd | wc -l)
6805
6806         [ $nums -eq $expected ] ||
6807                 error "'$cmd' wrong: found $nums, expected $expected"
6808 }
6809 run_test 56n "check lfs find -type l"
6810
6811 test_56o() {
6812         local dir=$DIR/$tdir
6813
6814         setup_56 $dir $NUMFILES $NUMDIRS
6815         utime $dir/file1 > /dev/null || error "utime (1)"
6816         utime $dir/file2 > /dev/null || error "utime (2)"
6817         utime $dir/dir1 > /dev/null || error "utime (3)"
6818         utime $dir/dir2 > /dev/null || error "utime (4)"
6819         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6820         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6821
6822         local expected=4
6823         local nums=$($LFS find -mtime +0 $dir | wc -l)
6824
6825         [ $nums -eq $expected ] ||
6826                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6827
6828         expected=12
6829         cmd="$LFS find -mtime 0 $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56o "check lfs find -mtime for old files"
6835
6836 test_56ob() {
6837         local dir=$DIR/$tdir
6838         local expected=1
6839         local count=0
6840
6841         # just to make sure there is something that won't be found
6842         test_mkdir $dir
6843         touch $dir/$tfile.now
6844
6845         for age in year week day hour min; do
6846                 count=$((count + 1))
6847
6848                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6849                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6850                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6851
6852                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6853                 local nums=$($cmd | wc -l)
6854                 [ $nums -eq $expected ] ||
6855                         error "'$cmd' wrong: found $nums, expected $expected"
6856
6857                 cmd="$LFS find $dir -atime $count${age:0:1}"
6858                 nums=$($cmd | wc -l)
6859                 [ $nums -eq $expected ] ||
6860                         error "'$cmd' wrong: found $nums, expected $expected"
6861         done
6862
6863         sleep 2
6864         cmd="$LFS find $dir -ctime +1s -type f"
6865         nums=$($cmd | wc -l)
6866         (( $nums == $count * 2 + 1)) ||
6867                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6868 }
6869 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6870
6871 test_newerXY_base() {
6872         local x=$1
6873         local y=$2
6874         local dir=$DIR/$tdir
6875         local ref
6876         local negref
6877
6878         if [ $y == "t" ]; then
6879                 if [ $x == "b" ]; then
6880                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6881                 else
6882                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6883                 fi
6884         else
6885                 ref=$DIR/$tfile.newer.$x$y
6886                 touch $ref || error "touch $ref failed"
6887         fi
6888
6889         echo "before = $ref"
6890         sleep 2
6891         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6892         sleep 2
6893         if [ $y == "t" ]; then
6894                 if [ $x == "b" ]; then
6895                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6896                 else
6897                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6898                 fi
6899         else
6900                 negref=$DIR/$tfile.negnewer.$x$y
6901                 touch $negref || error "touch $negref failed"
6902         fi
6903
6904         echo "after = $negref"
6905         local cmd="$LFS find $dir -newer$x$y $ref"
6906         local nums=$(eval $cmd | wc -l)
6907         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6908
6909         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6910                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6911
6912         cmd="$LFS find $dir ! -newer$x$y $negref"
6913         nums=$(eval $cmd | wc -l)
6914         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6915                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6916
6917         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6918         nums=$(eval $cmd | wc -l)
6919         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6920                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6921
6922         rm -rf $DIR/*
6923 }
6924
6925 test_56oc() {
6926         test_newerXY_base "a" "a"
6927         test_newerXY_base "a" "m"
6928         test_newerXY_base "a" "c"
6929         test_newerXY_base "m" "a"
6930         test_newerXY_base "m" "m"
6931         test_newerXY_base "m" "c"
6932         test_newerXY_base "c" "a"
6933         test_newerXY_base "c" "m"
6934         test_newerXY_base "c" "c"
6935
6936         test_newerXY_base "a" "t"
6937         test_newerXY_base "m" "t"
6938         test_newerXY_base "c" "t"
6939
6940         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6941            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6942                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6943
6944         test_newerXY_base "b" "b"
6945         test_newerXY_base "b" "t"
6946 }
6947 run_test 56oc "check lfs find -newerXY work"
6948
6949 test_56od() {
6950         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6951                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6952
6953         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6954                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6955
6956         local dir=$DIR/$tdir
6957         local ref=$DIR/$tfile.ref
6958         local negref=$DIR/$tfile.negref
6959
6960         mkdir $dir || error "mkdir $dir failed"
6961         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6962         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6963         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6964         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6965         touch $ref || error "touch $ref failed"
6966         # sleep 3 seconds at least
6967         sleep 3
6968
6969         local before=$(do_facet mds1 date +%s)
6970         local skew=$(($(date +%s) - before + 1))
6971
6972         if (( skew < 0 && skew > -5 )); then
6973                 sleep $((0 - skew + 1))
6974                 skew=0
6975         fi
6976
6977         # Set the dir stripe params to limit files all on MDT0,
6978         # otherwise we need to calc the max clock skew between
6979         # the client and MDTs.
6980         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6981         sleep 2
6982         touch $negref || error "touch $negref failed"
6983
6984         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6985         local nums=$($cmd | wc -l)
6986         local expected=$(((NUMFILES + 1) * NUMDIRS))
6987
6988         [ $nums -eq $expected ] ||
6989                 error "'$cmd' wrong: found $nums, expected $expected"
6990
6991         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6992         nums=$($cmd | wc -l)
6993         expected=$((NUMFILES + 1))
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996
6997         [ $skew -lt 0 ] && return
6998
6999         local after=$(do_facet mds1 date +%s)
7000         local age=$((after - before + 1 + skew))
7001
7002         cmd="$LFS find $dir -btime -${age}s -type f"
7003         nums=$($cmd | wc -l)
7004         expected=$(((NUMFILES + 1) * NUMDIRS))
7005
7006         echo "Clock skew between client and server: $skew, age:$age"
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         expected=$(($NUMDIRS + 1))
7011         cmd="$LFS find $dir -btime -${age}s -type d"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015         rm -f $ref $negref || error "Failed to remove $ref $negref"
7016 }
7017 run_test 56od "check lfs find -btime with units"
7018
7019 test_56p() {
7020         [ $RUNAS_ID -eq $UID ] &&
7021                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7022
7023         local dir=$DIR/$tdir
7024
7025         setup_56 $dir $NUMFILES $NUMDIRS
7026         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7027
7028         local expected=$NUMFILES
7029         local cmd="$LFS find -uid $RUNAS_ID $dir"
7030         local nums=$($cmd | wc -l)
7031
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034
7035         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7036         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7037         nums=$($cmd | wc -l)
7038         [ $nums -eq $expected ] ||
7039                 error "'$cmd' wrong: found $nums, expected $expected"
7040 }
7041 run_test 56p "check lfs find -uid and ! -uid"
7042
7043 test_56q() {
7044         [ $RUNAS_ID -eq $UID ] &&
7045                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7046
7047         local dir=$DIR/$tdir
7048
7049         setup_56 $dir $NUMFILES $NUMDIRS
7050         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7051
7052         local expected=$NUMFILES
7053         local cmd="$LFS find -gid $RUNAS_GID $dir"
7054         local nums=$($cmd | wc -l)
7055
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058
7059         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7060         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] ||
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064 }
7065 run_test 56q "check lfs find -gid and ! -gid"
7066
7067 test_56r() {
7068         local dir=$DIR/$tdir
7069
7070         setup_56 $dir $NUMFILES $NUMDIRS
7071
7072         local expected=12
7073         local cmd="$LFS find -size 0 -type f -lazy $dir"
7074         local nums=$($cmd | wc -l)
7075
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078         cmd="$LFS find -size 0 -type f $dir"
7079         nums=$($cmd | wc -l)
7080         [ $nums -eq $expected ] ||
7081                 error "'$cmd' wrong: found $nums, expected $expected"
7082
7083         expected=0
7084         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] ||
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         cmd="$LFS find ! -size 0 -type f $dir"
7089         nums=$($cmd | wc -l)
7090         [ $nums -eq $expected ] ||
7091                 error "'$cmd' wrong: found $nums, expected $expected"
7092
7093         echo "test" > $dir/$tfile
7094         echo "test2" > $dir/$tfile.2 && sync
7095         expected=1
7096         cmd="$LFS find -size 5 -type f -lazy $dir"
7097         nums=$($cmd | wc -l)
7098         [ $nums -eq $expected ] ||
7099                 error "'$cmd' wrong: found $nums, expected $expected"
7100         cmd="$LFS find -size 5 -type f $dir"
7101         nums=$($cmd | wc -l)
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=1
7106         cmd="$LFS find -size +5 -type f -lazy $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110         cmd="$LFS find -size +5 -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114
7115         expected=2
7116         cmd="$LFS find -size +0 -type f -lazy $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120         cmd="$LFS find -size +0 -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         expected=2
7126         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130         cmd="$LFS find ! -size -5 -type f $dir"
7131         nums=$($cmd | wc -l)
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134
7135         expected=12
7136         cmd="$LFS find -size -5 -type f -lazy $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140         cmd="$LFS find -size -5 -type f $dir"
7141         nums=$($cmd | wc -l)
7142         [ $nums -eq $expected ] ||
7143                 error "'$cmd' wrong: found $nums, expected $expected"
7144 }
7145 run_test 56r "check lfs find -size works"
7146
7147 test_56ra_sub() {
7148         local expected=$1
7149         local glimpses=$2
7150         local cmd="$3"
7151
7152         cancel_lru_locks $OSC
7153
7154         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7155         local nums=$($cmd | wc -l)
7156
7157         [ $nums -eq $expected ] ||
7158                 error "'$cmd' wrong: found $nums, expected $expected"
7159
7160         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7161
7162         if (( rpcs_before + glimpses != rpcs_after )); then
7163                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7164                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7165
7166                 if [[ $glimpses == 0 ]]; then
7167                         error "'$cmd' should not send glimpse RPCs to OST"
7168                 else
7169                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7170                 fi
7171         fi
7172 }
7173
7174 test_56ra() {
7175         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7176                 skip "MDS < 2.12.58 doesn't return LSOM data"
7177         local dir=$DIR/$tdir
7178         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7179
7180         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7181
7182         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7183         $LCTL set_param -n llite.*.statahead_agl=0
7184         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7185
7186         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7187         # open and close all files to ensure LSOM is updated
7188         cancel_lru_locks $OSC
7189         find $dir -type f | xargs cat > /dev/null
7190
7191         #   expect_found  glimpse_rpcs  command_to_run
7192         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7193         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7194         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7195         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7196
7197         echo "test" > $dir/$tfile
7198         echo "test2" > $dir/$tfile.2 && sync
7199         cancel_lru_locks $OSC
7200         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7201
7202         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7203         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7204         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7205         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7206
7207         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7208         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7209         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7210         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7211         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7212         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7213 }
7214 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7215
7216 test_56rb() {
7217         local dir=$DIR/$tdir
7218         local tmp=$TMP/$tfile.log
7219         local mdt_idx;
7220
7221         test_mkdir -p $dir || error "failed to mkdir $dir"
7222         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7223                 error "failed to setstripe $dir/$tfile"
7224         mdt_idx=$($LFS getdirstripe -i $dir)
7225         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7226
7227         stack_trap "rm -f $tmp" EXIT
7228         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7229         ! grep -q obd_uuid $tmp ||
7230                 error "failed to find --size +100K --ost 0 $dir"
7231         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7232         ! grep -q obd_uuid $tmp ||
7233                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7234 }
7235 run_test 56rb "check lfs find --size --ost/--mdt works"
7236
7237 test_56rc() {
7238         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7239         local dir=$DIR/$tdir
7240         local found
7241
7242         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7243         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7244         (( $MDSCOUNT > 2 )) &&
7245                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7246         mkdir $dir/$tdir-{1..10}
7247         touch $dir/$tfile-{1..10}
7248
7249         found=$($LFS find $dir --mdt-count 2 | wc -l)
7250         expect=11
7251         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7252
7253         found=$($LFS find $dir -T +1 | wc -l)
7254         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7255         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7256
7257         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7258         expect=11
7259         (( $found == $expect )) || error "found $found all_char, expect $expect"
7260
7261         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7262         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7263         (( $found == $expect )) || error "found $found all_char, expect $expect"
7264 }
7265 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7266
7267 test_56rd() {
7268         local dir=$DIR/$tdir
7269
7270         test_mkdir $dir
7271         rm -f $dir/*
7272
7273         mkfifo $dir/fifo || error "failed to create fifo file"
7274         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7275                 error "should not fail even cannot get projid from pipe file"
7276         found=$($LFS find $dir -t p --printf "%y")
7277         [[ "p" == $found ]] || error "found $found, expect p"
7278
7279         mknod $dir/chardev c 1 5 ||
7280                 error "failed to create character device file"
7281         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7282                 error "should not fail even cannot get projid from chardev file"
7283         found=$($LFS find $dir -t c --printf "%y")
7284         [[ "c" == $found ]] || error "found $found, expect c"
7285
7286         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7287         (( found == 2 )) || error "unable to list all files"
7288 }
7289 run_test 56rd "check lfs find --printf special files"
7290
7291 test_56s() { # LU-611 #LU-9369
7292         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7293
7294         local dir=$DIR/$tdir
7295         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7296
7297         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7298         for i in $(seq $NUMDIRS); do
7299                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7300         done
7301
7302         local expected=$NUMDIRS
7303         local cmd="$LFS find -c $OSTCOUNT $dir"
7304         local nums=$($cmd | wc -l)
7305
7306         [ $nums -eq $expected ] || {
7307                 $LFS getstripe -R $dir
7308                 error "'$cmd' wrong: found $nums, expected $expected"
7309         }
7310
7311         expected=$((NUMDIRS + onestripe))
7312         cmd="$LFS find -stripe-count +0 -type f $dir"
7313         nums=$($cmd | wc -l)
7314         [ $nums -eq $expected ] || {
7315                 $LFS getstripe -R $dir
7316                 error "'$cmd' wrong: found $nums, expected $expected"
7317         }
7318
7319         expected=$onestripe
7320         cmd="$LFS find -stripe-count 1 -type f $dir"
7321         nums=$($cmd | wc -l)
7322         [ $nums -eq $expected ] || {
7323                 $LFS getstripe -R $dir
7324                 error "'$cmd' wrong: found $nums, expected $expected"
7325         }
7326
7327         cmd="$LFS find -stripe-count -2 -type f $dir"
7328         nums=$($cmd | wc -l)
7329         [ $nums -eq $expected ] || {
7330                 $LFS getstripe -R $dir
7331                 error "'$cmd' wrong: found $nums, expected $expected"
7332         }
7333
7334         expected=0
7335         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7336         nums=$($cmd | wc -l)
7337         [ $nums -eq $expected ] || {
7338                 $LFS getstripe -R $dir
7339                 error "'$cmd' wrong: found $nums, expected $expected"
7340         }
7341 }
7342 run_test 56s "check lfs find -stripe-count works"
7343
7344 test_56t() { # LU-611 #LU-9369
7345         local dir=$DIR/$tdir
7346
7347         setup_56 $dir 0 $NUMDIRS
7348         for i in $(seq $NUMDIRS); do
7349                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7350         done
7351
7352         local expected=$NUMDIRS
7353         local cmd="$LFS find -S 8M $dir"
7354         local nums=$($cmd | wc -l)
7355
7356         [ $nums -eq $expected ] || {
7357                 $LFS getstripe -R $dir
7358                 error "'$cmd' wrong: found $nums, expected $expected"
7359         }
7360         rm -rf $dir
7361
7362         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7363
7364         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7365
7366         expected=$(((NUMDIRS + 1) * NUMFILES))
7367         cmd="$LFS find -stripe-size 512k -type f $dir"
7368         nums=$($cmd | wc -l)
7369         [ $nums -eq $expected ] ||
7370                 error "'$cmd' wrong: found $nums, expected $expected"
7371
7372         cmd="$LFS find -stripe-size +320k -type f $dir"
7373         nums=$($cmd | wc -l)
7374         [ $nums -eq $expected ] ||
7375                 error "'$cmd' wrong: found $nums, expected $expected"
7376
7377         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7378         cmd="$LFS find -stripe-size +200k -type f $dir"
7379         nums=$($cmd | wc -l)
7380         [ $nums -eq $expected ] ||
7381                 error "'$cmd' wrong: found $nums, expected $expected"
7382
7383         cmd="$LFS find -stripe-size -640k -type f $dir"
7384         nums=$($cmd | wc -l)
7385         [ $nums -eq $expected ] ||
7386                 error "'$cmd' wrong: found $nums, expected $expected"
7387
7388         expected=4
7389         cmd="$LFS find -stripe-size 256k -type f $dir"
7390         nums=$($cmd | wc -l)
7391         [ $nums -eq $expected ] ||
7392                 error "'$cmd' wrong: found $nums, expected $expected"
7393
7394         cmd="$LFS find -stripe-size -320k -type f $dir"
7395         nums=$($cmd | wc -l)
7396         [ $nums -eq $expected ] ||
7397                 error "'$cmd' wrong: found $nums, expected $expected"
7398
7399         expected=0
7400         cmd="$LFS find -stripe-size 1024k -type f $dir"
7401         nums=$($cmd | wc -l)
7402         [ $nums -eq $expected ] ||
7403                 error "'$cmd' wrong: found $nums, expected $expected"
7404 }
7405 run_test 56t "check lfs find -stripe-size works"
7406
7407 test_56u() { # LU-611
7408         local dir=$DIR/$tdir
7409
7410         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7411
7412         if [[ $OSTCOUNT -gt 1 ]]; then
7413                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7414                 onestripe=4
7415         else
7416                 onestripe=0
7417         fi
7418
7419         local expected=$(((NUMDIRS + 1) * NUMFILES))
7420         local cmd="$LFS find -stripe-index 0 -type f $dir"
7421         local nums=$($cmd | wc -l)
7422
7423         [ $nums -eq $expected ] ||
7424                 error "'$cmd' wrong: found $nums, expected $expected"
7425
7426         expected=$onestripe
7427         cmd="$LFS find -stripe-index 1 -type f $dir"
7428         nums=$($cmd | wc -l)
7429         [ $nums -eq $expected ] ||
7430                 error "'$cmd' wrong: found $nums, expected $expected"
7431
7432         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7433         nums=$($cmd | wc -l)
7434         [ $nums -eq $expected ] ||
7435                 error "'$cmd' wrong: found $nums, expected $expected"
7436
7437         expected=0
7438         # This should produce an error and not return any files
7439         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7440         nums=$($cmd 2>/dev/null | wc -l)
7441         [ $nums -eq $expected ] ||
7442                 error "'$cmd' wrong: found $nums, expected $expected"
7443
7444         if [[ $OSTCOUNT -gt 1 ]]; then
7445                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7446                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7447                 nums=$($cmd | wc -l)
7448                 [ $nums -eq $expected ] ||
7449                         error "'$cmd' wrong: found $nums, expected $expected"
7450         fi
7451 }
7452 run_test 56u "check lfs find -stripe-index works"
7453
7454 test_56v() {
7455         local mdt_idx=0
7456         local dir=$DIR/$tdir
7457
7458         setup_56 $dir $NUMFILES $NUMDIRS
7459
7460         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7461         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7462
7463         for file in $($LFS find -m $UUID $dir); do
7464                 file_midx=$($LFS getstripe -m $file)
7465                 [ $file_midx -eq $mdt_idx ] ||
7466                         error "lfs find -m $UUID != getstripe -m $file_midx"
7467         done
7468 }
7469 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7470
7471 test_56wa() {
7472         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7474
7475         local dir=$DIR/$tdir
7476
7477         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7478         stack_trap "rm -rf $dir"
7479
7480         local stripe_size=$($LFS getstripe -S -d $dir) ||
7481                 error "$LFS getstripe -S -d $dir failed"
7482         stripe_size=${stripe_size%% *}
7483
7484         local file_size=$((stripe_size * OSTCOUNT))
7485         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7486         local required_space=$((file_num * file_size))
7487         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7488                            head -n1)
7489         (( free_space >= required_space / 1024 )) ||
7490                 skip_env "need $required_space, have $free_space kbytes"
7491
7492         local dd_bs=65536
7493         local dd_count=$((file_size / dd_bs))
7494
7495         # write data into the files
7496         local i
7497         local j
7498         local file
7499
7500         for ((i = 1; i <= NUMFILES; i++ )); do
7501                 file=$dir/file$i
7502                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7503                         error "write data into $file failed"
7504         done
7505         for ((i = 1; i <= NUMDIRS; i++ )); do
7506                 for ((j = 1; j <= NUMFILES; j++ )); do
7507                         file=$dir/dir$i/file$j
7508                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7509                                 error "write data into $file failed"
7510                 done
7511         done
7512
7513         # $LFS_MIGRATE will fail if hard link migration is unsupported
7514         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7515                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7516                         error "creating links to $dir/dir1/file1 failed"
7517         fi
7518
7519         local expected=-1
7520
7521         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7522
7523         # lfs_migrate file
7524         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7525
7526         echo "$cmd"
7527         eval $cmd || error "$cmd failed"
7528
7529         check_stripe_count $dir/file1 $expected
7530
7531         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7532                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7533                 # OST 1 if it is on OST 0. This file is small enough to
7534                 # be on only one stripe.
7535                 file=$dir/migr_1_ost
7536                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7537                         error "write data into $file failed"
7538                 local obdidx=$($LFS getstripe -i $file)
7539                 local oldmd5=$(md5sum $file)
7540                 local newobdidx=0
7541
7542                 (( obdidx != 0 )) || newobdidx=1
7543                 cmd="$LFS migrate -i $newobdidx $file"
7544                 echo $cmd
7545                 eval $cmd || error "$cmd failed"
7546
7547                 local realobdix=$($LFS getstripe -i $file)
7548                 local newmd5=$(md5sum $file)
7549
7550                 (( $newobdidx == $realobdix )) ||
7551                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7552                 [[ "$oldmd5" == "$newmd5" ]] ||
7553                         error "md5sum differ: $oldmd5, $newmd5"
7554         fi
7555
7556         # lfs_migrate dir
7557         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7558         echo "$cmd"
7559         eval $cmd || error "$cmd failed"
7560
7561         for (( j = 1; j <= NUMFILES; j++ )); do
7562                 check_stripe_count $dir/dir1/file$j $expected
7563         done
7564
7565         # lfs_migrate works with lfs find
7566         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7567              $LFS_MIGRATE -y -c $expected"
7568         echo "$cmd"
7569         eval $cmd || error "$cmd failed"
7570
7571         for (( i = 2; i <= NUMFILES; i++ )); do
7572                 check_stripe_count $dir/file$i $expected
7573         done
7574         for (( i = 2; i <= NUMDIRS; i++ )); do
7575                 for (( j = 1; j <= NUMFILES; j++ )); do
7576                         check_stripe_count $dir/dir$i/file$j $expected
7577                 done
7578         done
7579 }
7580 run_test 56wa "check lfs_migrate -c stripe_count works"
7581
7582 test_56wb() {
7583         local file1=$DIR/$tdir/file1
7584         local create_pool=false
7585         local initial_pool=$($LFS getstripe -p $DIR)
7586         local pool_list=()
7587         local pool=""
7588
7589         echo -n "Creating test dir..."
7590         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7591         echo "done."
7592
7593         echo -n "Creating test file..."
7594         touch $file1 || error "cannot create file"
7595         echo "done."
7596
7597         echo -n "Detecting existing pools..."
7598         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7599
7600         if [ ${#pool_list[@]} -gt 0 ]; then
7601                 echo "${pool_list[@]}"
7602                 for thispool in "${pool_list[@]}"; do
7603                         if [[ -z "$initial_pool" ||
7604                               "$initial_pool" != "$thispool" ]]; then
7605                                 pool="$thispool"
7606                                 echo "Using existing pool '$pool'"
7607                                 break
7608                         fi
7609                 done
7610         else
7611                 echo "none detected."
7612         fi
7613         if [ -z "$pool" ]; then
7614                 pool=${POOL:-testpool}
7615                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7616                 echo -n "Creating pool '$pool'..."
7617                 create_pool=true
7618                 pool_add $pool &> /dev/null ||
7619                         error "pool_add failed"
7620                 echo "done."
7621
7622                 echo -n "Adding target to pool..."
7623                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7624                         error "pool_add_targets failed"
7625                 echo "done."
7626         fi
7627
7628         echo -n "Setting pool using -p option..."
7629         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7630                 error "migrate failed rc = $?"
7631         echo "done."
7632
7633         echo -n "Verifying test file is in pool after migrating..."
7634         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7635                 error "file was not migrated to pool $pool"
7636         echo "done."
7637
7638         echo -n "Removing test file from pool '$pool'..."
7639         # "lfs migrate $file" won't remove the file from the pool
7640         # until some striping information is changed.
7641         $LFS migrate -c 1 $file1 &> /dev/null ||
7642                 error "cannot remove from pool"
7643         [ "$($LFS getstripe -p $file1)" ] &&
7644                 error "pool still set"
7645         echo "done."
7646
7647         echo -n "Setting pool using --pool option..."
7648         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7649                 error "migrate failed rc = $?"
7650         echo "done."
7651
7652         # Clean up
7653         rm -f $file1
7654         if $create_pool; then
7655                 destroy_test_pools 2> /dev/null ||
7656                         error "destroy test pools failed"
7657         fi
7658 }
7659 run_test 56wb "check lfs_migrate pool support"
7660
7661 test_56wc() {
7662         local file1="$DIR/$tdir/$tfile"
7663         local md5
7664         local parent_ssize
7665         local parent_scount
7666         local cur_ssize
7667         local cur_scount
7668         local orig_ssize
7669         local new_scount
7670         local cur_comp
7671
7672         echo -n "Creating test dir..."
7673         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7674         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7675                 error "cannot set stripe by '-S 1M -c 1'"
7676         echo "done"
7677
7678         echo -n "Setting initial stripe for test file..."
7679         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7680                 error "cannot set stripe"
7681         cur_ssize=$($LFS getstripe -S "$file1")
7682         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7683         echo "done."
7684
7685         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7686         stack_trap "rm -f $file1"
7687         md5="$(md5sum $file1)"
7688
7689         # File currently set to -S 512K -c 1
7690
7691         # Ensure -c and -S options are rejected when -R is set
7692         echo -n "Verifying incompatible options are detected..."
7693         $LFS_MIGRATE -R -c 1 "$file1" &&
7694                 error "incompatible -R and -c options not detected"
7695         $LFS_MIGRATE -R -S 1M "$file1" &&
7696                 error "incompatible -R and -S options not detected"
7697         $LFS_MIGRATE -R -p pool "$file1" &&
7698                 error "incompatible -R and -p options not detected"
7699         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7700                 error "incompatible -R and -E options not detected"
7701         $LFS_MIGRATE -R -A "$file1" &&
7702                 error "incompatible -R and -A options not detected"
7703         $LFS_MIGRATE -A -c 1 "$file1" &&
7704                 error "incompatible -A and -c options not detected"
7705         $LFS_MIGRATE -A -S 1M "$file1" &&
7706                 error "incompatible -A and -S options not detected"
7707         $LFS_MIGRATE -A -p pool "$file1" &&
7708                 error "incompatible -A and -p options not detected"
7709         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7710                 error "incompatible -A and -E options not detected"
7711         echo "done."
7712
7713         # Ensure unrecognized options are passed through to 'lfs migrate'
7714         echo -n "Verifying -S option is passed through to lfs migrate..."
7715         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7716         cur_ssize=$($LFS getstripe -S "$file1")
7717         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7718         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7719         echo "done."
7720
7721         # File currently set to -S 1M -c 1
7722
7723         # Ensure long options are supported
7724         echo -n "Verifying long options supported..."
7725         $LFS_MIGRATE --non-block "$file1" ||
7726                 error "long option without argument not supported"
7727         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7728                 error "long option with argument not supported"
7729         cur_ssize=$($LFS getstripe -S "$file1")
7730         (( cur_ssize == 524288 )) ||
7731                 error "migrate --stripe-size $cur_ssize != 524288"
7732         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7733         echo "done."
7734
7735         # File currently set to -S 512K -c 1
7736
7737         if (( OSTCOUNT > 1 )); then
7738                 echo -n "Verifying explicit stripe count can be set..."
7739                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7740                 cur_scount=$($LFS getstripe -c "$file1")
7741                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7742                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7743                         error "file data has changed (3)"
7744                 echo "done."
7745         fi
7746
7747         # File currently set to -S 512K -c 1 or -S 512K -c 2
7748
7749         # Ensure parent striping is used if -R is set, and no stripe
7750         # count or size is specified
7751         echo -n "Setting stripe for parent directory..."
7752         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7753                 error "cannot set stripe '-S 2M -c 1'"
7754         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7755         echo "done."
7756
7757         echo -n "Verifying restripe option uses parent stripe settings..."
7758         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7759         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7760         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7761         cur_ssize=$($LFS getstripe -S "$file1")
7762         (( cur_ssize == parent_ssize )) ||
7763                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7764         cur_scount=$($LFS getstripe -c "$file1")
7765         (( cur_scount == parent_scount )) ||
7766                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7767         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7768         echo "done."
7769
7770         # File currently set to -S 1M -c 1
7771
7772         # Ensure striping is preserved if -R is not set, and no stripe
7773         # count or size is specified
7774         echo -n "Verifying striping size preserved when not specified..."
7775         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7776         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7777                 error "cannot set stripe on parent directory"
7778         $LFS_MIGRATE "$file1" || error "migrate failed"
7779         cur_ssize=$($LFS getstripe -S "$file1")
7780         (( cur_ssize == orig_ssize )) ||
7781                 error "migrate by default $cur_ssize != $orig_ssize"
7782         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7783         echo "done."
7784
7785         # Ensure file name properly detected when final option has no argument
7786         echo -n "Verifying file name properly detected..."
7787         $LFS_MIGRATE "$file1" ||
7788                 error "file name interpreted as option argument"
7789         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7790         echo "done."
7791
7792         # Ensure PFL arguments are passed through properly
7793         echo -n "Verifying PFL options passed through..."
7794         new_scount=$(((OSTCOUNT + 1) / 2))
7795         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7796                 error "migrate PFL arguments failed"
7797         cur_comp=$($LFS getstripe --comp-count $file1)
7798         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7799         cur_scount=$($LFS getstripe --stripe-count $file1)
7800         (( cur_scount == new_scount)) ||
7801                 error "PFL stripe count $cur_scount != $new_scount"
7802         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7803         echo "done."
7804 }
7805 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7806
7807 test_56wd() {
7808         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7809
7810         local file1=$DIR/$tdir/$tfile
7811
7812         echo -n "Creating test dir..."
7813         test_mkdir $DIR/$tdir || error "cannot create dir"
7814         echo "done."
7815
7816         echo -n "Creating test file..."
7817         echo "$tfile" > $file1
7818         echo "done."
7819
7820         # Ensure 'lfs migrate' will fail by using a non-existent option,
7821         # and make sure rsync is not called to recover
7822         echo -n "Make sure --no-rsync option works..."
7823         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7824                 grep -q 'refusing to fall back to rsync' ||
7825                 error "rsync was called with --no-rsync set"
7826         echo "done."
7827
7828         # Ensure rsync is called without trying 'lfs migrate' first
7829         echo -n "Make sure --rsync option works..."
7830         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7831                 grep -q 'falling back to rsync' &&
7832                 error "lfs migrate was called with --rsync set"
7833         echo "done."
7834 }
7835 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7836
7837 test_56we() {
7838         local td=$DIR/$tdir
7839         local tf=$td/$tfile
7840
7841         test_mkdir $td || error "cannot create $td"
7842         touch $tf || error "cannot touch $tf"
7843
7844         echo -n "Make sure --non-direct|-D works..."
7845         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7846                 grep -q "lfs migrate --non-direct" ||
7847                 error "--non-direct option cannot work correctly"
7848         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7849                 grep -q "lfs migrate -D" ||
7850                 error "-D option cannot work correctly"
7851         echo "done."
7852 }
7853 run_test 56we "check lfs_migrate --non-direct|-D support"
7854
7855 test_56x() {
7856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7857         check_swap_layouts_support
7858
7859         local dir=$DIR/$tdir
7860         local ref1=/etc/passwd
7861         local file1=$dir/file1
7862
7863         test_mkdir $dir || error "creating dir $dir"
7864         $LFS setstripe -c 2 $file1
7865         cp $ref1 $file1
7866         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7867         stripe=$($LFS getstripe -c $file1)
7868         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7869         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7870
7871         # clean up
7872         rm -f $file1
7873 }
7874 run_test 56x "lfs migration support"
7875
7876 test_56xa() {
7877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7878         check_swap_layouts_support
7879
7880         local dir=$DIR/$tdir/$testnum
7881
7882         test_mkdir -p $dir
7883
7884         local ref1=/etc/passwd
7885         local file1=$dir/file1
7886
7887         $LFS setstripe -c 2 $file1
7888         cp $ref1 $file1
7889         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7890
7891         local stripe=$($LFS getstripe -c $file1)
7892
7893         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7894         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7895
7896         # clean up
7897         rm -f $file1
7898 }
7899 run_test 56xa "lfs migration --block support"
7900
7901 check_migrate_links() {
7902         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7903         local dir="$1"
7904         local file1="$dir/file1"
7905         local begin="$2"
7906         local count="$3"
7907         local runas="$4"
7908         local total_count=$(($begin + $count - 1))
7909         local symlink_count=10
7910         local uniq_count=10
7911
7912         if [ ! -f "$file1" ]; then
7913                 echo -n "creating initial file..."
7914                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7915                         error "cannot setstripe initial file"
7916                 echo "done"
7917
7918                 echo -n "creating symlinks..."
7919                 for s in $(seq 1 $symlink_count); do
7920                         ln -s "$file1" "$dir/slink$s" ||
7921                                 error "cannot create symlinks"
7922                 done
7923                 echo "done"
7924
7925                 echo -n "creating nonlinked files..."
7926                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7927                         error "cannot create nonlinked files"
7928                 echo "done"
7929         fi
7930
7931         # create hard links
7932         if [ ! -f "$dir/file$total_count" ]; then
7933                 echo -n "creating hard links $begin:$total_count..."
7934                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7935                         /dev/null || error "cannot create hard links"
7936                 echo "done"
7937         fi
7938
7939         echo -n "checking number of hard links listed in xattrs..."
7940         local fid=$($LFS getstripe -F "$file1")
7941         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7942
7943         echo "${#paths[*]}"
7944         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7945                         skip "hard link list has unexpected size, skipping test"
7946         fi
7947         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7948                         error "link names should exceed xattrs size"
7949         fi
7950
7951         echo -n "migrating files..."
7952         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7953         local rc=$?
7954         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7955         echo "done"
7956
7957         # make sure all links have been properly migrated
7958         echo -n "verifying files..."
7959         fid=$($LFS getstripe -F "$file1") ||
7960                 error "cannot get fid for file $file1"
7961         for i in $(seq 2 $total_count); do
7962                 local fid2=$($LFS getstripe -F $dir/file$i)
7963
7964                 [ "$fid2" == "$fid" ] ||
7965                         error "migrated hard link has mismatched FID"
7966         done
7967
7968         # make sure hard links were properly detected, and migration was
7969         # performed only once for the entire link set; nonlinked files should
7970         # also be migrated
7971         local actual=$(grep -c 'done' <<< "$migrate_out")
7972         local expected=$(($uniq_count + 1))
7973
7974         [ "$actual" -eq  "$expected" ] ||
7975                 error "hard links individually migrated ($actual != $expected)"
7976
7977         # make sure the correct number of hard links are present
7978         local hardlinks=$(stat -c '%h' "$file1")
7979
7980         [ $hardlinks -eq $total_count ] ||
7981                 error "num hard links $hardlinks != $total_count"
7982         echo "done"
7983
7984         return 0
7985 }
7986
7987 test_56xb() {
7988         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7989                 skip "Need MDS version at least 2.10.55"
7990
7991         local dir="$DIR/$tdir"
7992
7993         test_mkdir "$dir" || error "cannot create dir $dir"
7994
7995         echo "testing lfs migrate mode when all links fit within xattrs"
7996         check_migrate_links "$dir" 2 99
7997
7998         echo "testing rsync mode when all links fit within xattrs"
7999         check_migrate_links --rsync "$dir" 2 99
8000
8001         echo "testing lfs migrate mode when all links do not fit within xattrs"
8002         check_migrate_links "$dir" 101 100
8003
8004         echo "testing rsync mode when all links do not fit within xattrs"
8005         check_migrate_links --rsync "$dir" 101 100
8006
8007         chown -R $RUNAS_ID $dir
8008         echo "testing non-root lfs migrate mode when not all links are in xattr"
8009         check_migrate_links "$dir" 101 100 "$RUNAS"
8010
8011         # clean up
8012         rm -rf $dir
8013 }
8014 run_test 56xb "lfs migration hard link support"
8015
8016 test_56xc() {
8017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8018
8019         local dir="$DIR/$tdir"
8020
8021         test_mkdir "$dir" || error "cannot create dir $dir"
8022
8023         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8024         echo -n "Setting initial stripe for 20MB test file..."
8025         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8026                 error "cannot setstripe 20MB file"
8027         echo "done"
8028         echo -n "Sizing 20MB test file..."
8029         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8030         echo "done"
8031         echo -n "Verifying small file autostripe count is 1..."
8032         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8033                 error "cannot migrate 20MB file"
8034         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8035                 error "cannot get stripe for $dir/20mb"
8036         [ $stripe_count -eq 1 ] ||
8037                 error "unexpected stripe count $stripe_count for 20MB file"
8038         rm -f "$dir/20mb"
8039         echo "done"
8040
8041         # Test 2: File is small enough to fit within the available space on
8042         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8043         # have at least an additional 1KB for each desired stripe for test 3
8044         echo -n "Setting stripe for 1GB test file..."
8045         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8046         echo "done"
8047         echo -n "Sizing 1GB test file..."
8048         # File size is 1GB + 3KB
8049         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8050         echo "done"
8051
8052         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8053         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8054         if (( avail > 524288 * OSTCOUNT )); then
8055                 echo -n "Migrating 1GB file..."
8056                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8057                         error "cannot migrate 1GB file"
8058                 echo "done"
8059                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8060                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8061                         error "cannot getstripe for 1GB file"
8062                 [ $stripe_count -eq 2 ] ||
8063                         error "unexpected stripe count $stripe_count != 2"
8064                 echo "done"
8065         fi
8066
8067         # Test 3: File is too large to fit within the available space on
8068         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8069         if [ $OSTCOUNT -ge 3 ]; then
8070                 # The required available space is calculated as
8071                 # file size (1GB + 3KB) / OST count (3).
8072                 local kb_per_ost=349526
8073
8074                 echo -n "Migrating 1GB file with limit..."
8075                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8076                         error "cannot migrate 1GB file with limit"
8077                 echo "done"
8078
8079                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8080                 echo -n "Verifying 1GB autostripe count with limited space..."
8081                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8082                         error "unexpected stripe count $stripe_count (min 3)"
8083                 echo "done"
8084         fi
8085
8086         # clean up
8087         rm -rf $dir
8088 }
8089 run_test 56xc "lfs migration autostripe"
8090
8091 test_56xd() {
8092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8093
8094         local dir=$DIR/$tdir
8095         local f_mgrt=$dir/$tfile.mgrt
8096         local f_yaml=$dir/$tfile.yaml
8097         local f_copy=$dir/$tfile.copy
8098         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8099         local layout_copy="-c 2 -S 2M -i 1"
8100         local yamlfile=$dir/yamlfile
8101         local layout_before;
8102         local layout_after;
8103
8104         test_mkdir "$dir" || error "cannot create dir $dir"
8105         stack_trap "rm -rf $dir"
8106         $LFS setstripe $layout_yaml $f_yaml ||
8107                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8108         $LFS getstripe --yaml $f_yaml > $yamlfile
8109         $LFS setstripe $layout_copy $f_copy ||
8110                 error "cannot setstripe $f_copy with layout $layout_copy"
8111         touch $f_mgrt
8112         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8113
8114         # 1. test option --yaml
8115         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8116                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8117         layout_before=$(get_layout_param $f_yaml)
8118         layout_after=$(get_layout_param $f_mgrt)
8119         [ "$layout_after" == "$layout_before" ] ||
8120                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8121
8122         # 2. test option --copy
8123         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8124                 error "cannot migrate $f_mgrt with --copy $f_copy"
8125         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8126         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8127         [ "$layout_after" == "$layout_before" ] ||
8128                 error "lfs_migrate --copy: $layout_after != $layout_before"
8129 }
8130 run_test 56xd "check lfs_migrate --yaml and --copy support"
8131
8132 test_56xe() {
8133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8134
8135         local dir=$DIR/$tdir
8136         local f_comp=$dir/$tfile
8137         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8138         local layout_before=""
8139         local layout_after=""
8140
8141         test_mkdir "$dir" || error "cannot create dir $dir"
8142         stack_trap "rm -rf $dir"
8143         $LFS setstripe $layout $f_comp ||
8144                 error "cannot setstripe $f_comp with layout $layout"
8145         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8146         dd if=/dev/zero of=$f_comp bs=1M count=4
8147
8148         # 1. migrate a comp layout file by lfs_migrate
8149         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8150         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8151         [ "$layout_before" == "$layout_after" ] ||
8152                 error "lfs_migrate: $layout_before != $layout_after"
8153
8154         # 2. migrate a comp layout file by lfs migrate
8155         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8156         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8157         [ "$layout_before" == "$layout_after" ] ||
8158                 error "lfs migrate: $layout_before != $layout_after"
8159 }
8160 run_test 56xe "migrate a composite layout file"
8161
8162 test_56xf() {
8163         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8164
8165         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8166                 skip "Need server version at least 2.13.53"
8167
8168         local dir=$DIR/$tdir
8169         local f_comp=$dir/$tfile
8170         local layout="-E 1M -c1 -E -1 -c2"
8171         local fid_before=""
8172         local fid_after=""
8173
8174         test_mkdir "$dir" || error "cannot create dir $dir"
8175         stack_trap "rm -rf $dir"
8176         $LFS setstripe $layout $f_comp ||
8177                 error "cannot setstripe $f_comp with layout $layout"
8178         fid_before=$($LFS getstripe --fid $f_comp)
8179         dd if=/dev/zero of=$f_comp bs=1M count=4
8180
8181         # 1. migrate a comp layout file to a comp layout
8182         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8183         fid_after=$($LFS getstripe --fid $f_comp)
8184         [ "$fid_before" == "$fid_after" ] ||
8185                 error "comp-to-comp migrate: $fid_before != $fid_after"
8186
8187         # 2. migrate a comp layout file to a plain layout
8188         $LFS migrate -c2 $f_comp ||
8189                 error "cannot migrate $f_comp by lfs migrate"
8190         fid_after=$($LFS getstripe --fid $f_comp)
8191         [ "$fid_before" == "$fid_after" ] ||
8192                 error "comp-to-plain migrate: $fid_before != $fid_after"
8193
8194         # 3. migrate a plain layout file to a comp layout
8195         $LFS migrate $layout $f_comp ||
8196                 error "cannot migrate $f_comp by lfs migrate"
8197         fid_after=$($LFS getstripe --fid $f_comp)
8198         [ "$fid_before" == "$fid_after" ] ||
8199                 error "plain-to-comp migrate: $fid_before != $fid_after"
8200 }
8201 run_test 56xf "FID is not lost during migration of a composite layout file"
8202
8203 check_file_ost_range() {
8204         local file="$1"
8205         shift
8206         local range="$*"
8207         local -a file_range
8208         local idx
8209
8210         file_range=($($LFS getstripe -y "$file" |
8211                 awk '/l_ost_idx:/ { print $NF }'))
8212
8213         if [[ "${#file_range[@]}" = 0 ]]; then
8214                 echo "No osts found for $file"
8215                 return 1
8216         fi
8217
8218         for idx in "${file_range[@]}"; do
8219                 [[ " $range " =~ " $idx " ]] ||
8220                         return 1
8221         done
8222
8223         return 0
8224 }
8225
8226 sub_test_56xg() {
8227         local stripe_opt="$1"
8228         local pool="$2"
8229         shift 2
8230         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8231
8232         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8233                 error "Fail to migrate $tfile on $pool"
8234         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8235                 error "$tfile is not in pool $pool"
8236         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8237                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8238 }
8239
8240 test_56xg() {
8241         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8242         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8243         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8244                 skip "Need MDS version newer than 2.14.52"
8245
8246         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8247         local -a pool_ranges=("0 0" "1 1" "0 1")
8248
8249         # init pools
8250         for i in "${!pool_names[@]}"; do
8251                 pool_add ${pool_names[$i]} ||
8252                         error "pool_add failed (pool: ${pool_names[$i]})"
8253                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8254                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8255         done
8256
8257         # init the file to migrate
8258         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8259                 error "Unable to create $tfile on OST1"
8260         stack_trap "rm -f $DIR/$tfile"
8261         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8262                 error "Unable to write on $tfile"
8263
8264         echo "1. migrate $tfile on pool ${pool_names[0]}"
8265         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8266
8267         echo "2. migrate $tfile on pool ${pool_names[2]}"
8268         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8269
8270         echo "3. migrate $tfile on pool ${pool_names[1]}"
8271         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8272
8273         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8274         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8275         echo
8276
8277         # Clean pools
8278         destroy_test_pools ||
8279                 error "pool_destroy failed"
8280 }
8281 run_test 56xg "lfs migrate pool support"
8282
8283 test_56xh() {
8284         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8285
8286         local size_mb=25
8287         local file1=$DIR/$tfile
8288         local tmp1=$TMP/$tfile.tmp
8289
8290         $LFS setstripe -c 2 $file1
8291
8292         stack_trap "rm -f $file1 $tmp1"
8293         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8294                         error "error creating $tmp1"
8295         ls -lsh $tmp1
8296         cp $tmp1 $file1
8297
8298         local start=$SECONDS
8299
8300         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8301                 error "migrate failed rc = $?"
8302
8303         local elapsed=$((SECONDS - start))
8304
8305         # with 1MB/s, elapsed should equal size_mb
8306         (( elapsed >= size_mb * 95 / 100 )) ||
8307                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8308
8309         (( elapsed <= size_mb * 120 / 100 )) ||
8310                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8311
8312         (( elapsed <= size_mb * 350 / 100 )) ||
8313                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8314
8315         stripe=$($LFS getstripe -c $file1)
8316         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8317         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8318
8319         # Clean up file (since it is multiple MB)
8320         rm -f $file1 $tmp1
8321 }
8322 run_test 56xh "lfs migrate bandwidth limitation support"
8323
8324 test_56xi() {
8325         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8326         verify_yaml_available || skip_env "YAML verification not installed"
8327
8328         local size_mb=5
8329         local file1=$DIR/$tfile.1
8330         local file2=$DIR/$tfile.2
8331         local file3=$DIR/$tfile.3
8332         local output_file=$DIR/$tfile.out
8333         local tmp1=$TMP/$tfile.tmp
8334
8335         $LFS setstripe -c 2 $file1
8336         $LFS setstripe -c 2 $file2
8337         $LFS setstripe -c 2 $file3
8338
8339         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8340         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8341                         error "error creating $tmp1"
8342         ls -lsh $tmp1
8343         cp $tmp1 $file1
8344         cp $tmp1 $file2
8345         cp $tmp1 $file3
8346
8347         $LFS migrate --stats --stats-interval=1 \
8348                 -c 1 $file1 $file2 $file3 1> $output_file ||
8349                 error "migrate failed rc = $?"
8350
8351         cat $output_file
8352         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8353
8354         # Clean up file (since it is multiple MB)
8355         rm -f $file1 $file2 $file3 $tmp1 $output_file
8356 }
8357 run_test 56xi "lfs migrate stats support"
8358
8359 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8361
8362         local file=$DIR/$tfile
8363         local linkdir=$DIR/$tdir
8364
8365         test_mkdir $linkdir || error "fail to create $linkdir"
8366         $LFS setstripe -i 0 -c 1 -S1M $file
8367         stack_trap "rm -rf $file $linkdir"
8368         dd if=/dev/urandom of=$file bs=1M count=10 ||
8369                 error "fail to create $file"
8370
8371         # Create file links
8372         local cpts
8373         local threads_max
8374         local nlinks
8375
8376         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8377         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8378         (( nlinks = thread_max * 3 / 2 / cpts))
8379
8380         echo "create $nlinks hard links of $file"
8381         createmany -l $file $linkdir/link $nlinks
8382
8383         # Parallel migrates (should not block)
8384         local i
8385         for ((i = 0; i < nlinks; i++)); do
8386                 echo $linkdir/link$i
8387         done | xargs -n1 -P $nlinks $LFS migrate -c2
8388
8389         local stripe_count
8390         stripe_count=$($LFS getstripe -c $file) ||
8391                 error "fail to get stripe count on $file"
8392
8393         ((stripe_count == 2)) ||
8394                 error "fail to migrate $file (stripe_count = $stripe_count)"
8395 }
8396 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8397
8398 test_56xk() {
8399         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8400
8401         local size_mb=5
8402         local file1=$DIR/$tfile
8403
8404         stack_trap "rm -f $file1"
8405         $LFS setstripe -c 1 $file1
8406         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8407                 error "error creating $file1"
8408         $LFS mirror extend -N $file1 || error "can't mirror"
8409         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8410                 error "can't dd"
8411         $LFS getstripe $file1 | grep stale ||
8412                 error "one component must be stale"
8413
8414         local start=$SECONDS
8415         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8416                 error "migrate failed rc = $?"
8417         local elapsed=$((SECONDS - start))
8418         $LFS getstripe $file1 | grep stale &&
8419                 error "all components must be sync"
8420
8421         # with 1MB/s, elapsed should equal size_mb
8422         (( elapsed >= size_mb * 95 / 100 )) ||
8423                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8424
8425         (( elapsed <= size_mb * 120 / 100 )) ||
8426                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8427
8428         (( elapsed <= size_mb * 350 / 100 )) ||
8429                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8430 }
8431 run_test 56xk "lfs mirror resync bandwidth limitation support"
8432
8433 test_56xl() {
8434         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8435         verify_yaml_available || skip_env "YAML verification not installed"
8436
8437         local size_mb=5
8438         local file1=$DIR/$tfile.1
8439         local output_file=$DIR/$tfile.out
8440
8441         stack_trap "rm -f $file1"
8442         $LFS setstripe -c 1 $file1
8443         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8444                 error "error creating $file1"
8445         $LFS mirror extend -N $file1 || error "can't mirror"
8446         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8447                 error "can't dd"
8448         $LFS getstripe $file1 | grep stale ||
8449                 error "one component must be stale"
8450         $LFS getstripe $file1
8451
8452         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8453                 error "resync failed rc = $?"
8454         $LFS getstripe $file1 | grep stale &&
8455                 error "all components must be sync"
8456
8457         cat $output_file
8458         cat $output_file | verify_yaml || error "stats is not valid YAML"
8459 }
8460 run_test 56xl "lfs mirror resync stats support"
8461
8462 test_56y() {
8463         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8464                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8465
8466         local res=""
8467         local dir=$DIR/$tdir
8468         local f1=$dir/file1
8469         local f2=$dir/file2
8470
8471         test_mkdir -p $dir || error "creating dir $dir"
8472         touch $f1 || error "creating std file $f1"
8473         $MULTIOP $f2 H2c || error "creating released file $f2"
8474
8475         # a directory can be raid0, so ask only for files
8476         res=$($LFS find $dir -L raid0 -type f | wc -l)
8477         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8478
8479         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8480         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8481
8482         # only files can be released, so no need to force file search
8483         res=$($LFS find $dir -L released)
8484         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8485
8486         res=$($LFS find $dir -type f \! -L released)
8487         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8488 }
8489 run_test 56y "lfs find -L raid0|released"
8490
8491 test_56z() { # LU-4824
8492         # This checks to make sure 'lfs find' continues after errors
8493         # There are two classes of errors that should be caught:
8494         # - If multiple paths are provided, all should be searched even if one
8495         #   errors out
8496         # - If errors are encountered during the search, it should not terminate
8497         #   early
8498         local dir=$DIR/$tdir
8499         local i
8500
8501         test_mkdir $dir
8502         for i in d{0..9}; do
8503                 test_mkdir $dir/$i
8504                 touch $dir/$i/$tfile
8505         done
8506         $LFS find $DIR/non_existent_dir $dir &&
8507                 error "$LFS find did not return an error"
8508         # Make a directory unsearchable. This should NOT be the last entry in
8509         # directory order.  Arbitrarily pick the 6th entry
8510         chmod 700 $($LFS find $dir -type d | sed '6!d')
8511
8512         $RUNAS $LFS find $DIR/non_existent $dir
8513         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8514
8515         # The user should be able to see 10 directories and 9 files
8516         (( count == 19 )) ||
8517                 error "$LFS find found $count != 19 entries after error"
8518 }
8519 run_test 56z "lfs find should continue after an error"
8520
8521 test_56aa() { # LU-5937
8522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8523
8524         local dir=$DIR/$tdir
8525
8526         mkdir $dir
8527         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8528
8529         createmany -o $dir/striped_dir/${tfile}- 1024
8530         local dirs=$($LFS find --size +8k $dir/)
8531
8532         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8533 }
8534 run_test 56aa "lfs find --size under striped dir"
8535
8536 test_56ab() { # LU-10705
8537         test_mkdir $DIR/$tdir
8538         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8539         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8540         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8541         # Flush writes to ensure valid blocks.  Need to be more thorough for
8542         # ZFS, since blocks are not allocated/returned to client immediately.
8543         sync_all_data
8544         wait_zfs_commit ost1 2
8545         cancel_lru_locks osc
8546         ls -ls $DIR/$tdir
8547
8548         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8549
8550         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8551
8552         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8553         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8554
8555         rm -f $DIR/$tdir/$tfile.[123]
8556 }
8557 run_test 56ab "lfs find --blocks"
8558
8559 # LU-11188
8560 test_56aca() {
8561         local dir="$DIR/$tdir"
8562         local perms=(001 002 003 004 005 006 007
8563                      010 020 030 040 050 060 070
8564                      100 200 300 400 500 600 700
8565                      111 222 333 444 555 666 777)
8566         local perm_minus=(8 8 4 8 4 4 2
8567                           8 8 4 8 4 4 2
8568                           8 8 4 8 4 4 2
8569                           4 4 2 4 2 2 1)
8570         local perm_slash=(8  8 12  8 12 12 14
8571                           8  8 12  8 12 12 14
8572                           8  8 12  8 12 12 14
8573                          16 16 24 16 24 24 28)
8574
8575         test_mkdir "$dir"
8576         for perm in ${perms[*]}; do
8577                 touch "$dir/$tfile.$perm"
8578                 chmod $perm "$dir/$tfile.$perm"
8579         done
8580
8581         for ((i = 0; i < ${#perms[*]}; i++)); do
8582                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8583                 (( $num == 1 )) ||
8584                         error "lfs find -perm ${perms[i]}:"\
8585                               "$num != 1"
8586
8587                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8588                 (( $num == ${perm_minus[i]} )) ||
8589                         error "lfs find -perm -${perms[i]}:"\
8590                               "$num != ${perm_minus[i]}"
8591
8592                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8593                 (( $num == ${perm_slash[i]} )) ||
8594                         error "lfs find -perm /${perms[i]}:"\
8595                               "$num != ${perm_slash[i]}"
8596         done
8597 }
8598 run_test 56aca "check lfs find -perm with octal representation"
8599
8600 test_56acb() {
8601         local dir=$DIR/$tdir
8602         # p is the permission of write and execute for user, group and other
8603         # without the umask. It is used to test +wx.
8604         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8605         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8606         local symbolic=(+t  a+t u+t g+t o+t
8607                         g+s u+s o+s +s o+sr
8608                         o=r,ug+o,u+w
8609                         u+ g+ o+ a+ ugo+
8610                         u- g- o- a- ugo-
8611                         u= g= o= a= ugo=
8612                         o=r,ug+o,u+w u=r,a+u,u+w
8613                         g=r,ugo=g,u+w u+x,+X +X
8614                         u+x,u+X u+X u+x,g+X o+r,+X
8615                         u+x,go+X +wx +rwx)
8616
8617         test_mkdir $dir
8618         for perm in ${perms[*]}; do
8619                 touch "$dir/$tfile.$perm"
8620                 chmod $perm "$dir/$tfile.$perm"
8621         done
8622
8623         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8624                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8625
8626                 (( $num == 1 )) ||
8627                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8628         done
8629 }
8630 run_test 56acb "check lfs find -perm with symbolic representation"
8631
8632 test_56acc() {
8633         local dir=$DIR/$tdir
8634         local tests="17777 787 789 abcd
8635                 ug=uu ug=a ug=gu uo=ou urw
8636                 u+xg+x a=r,u+x,"
8637
8638         test_mkdir $dir
8639         for err in $tests; do
8640                 if $LFS find $dir -perm $err 2>/dev/null; then
8641                         error "lfs find -perm $err: parsing should have failed"
8642                 fi
8643         done
8644 }
8645 run_test 56acc "check parsing error for lfs find -perm"
8646
8647 test_56ba() {
8648         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8649                 skip "Need MDS version at least 2.10.50"
8650
8651         # Create composite files with one component
8652         local dir=$DIR/$tdir
8653
8654         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8655         # Create composite files with three components
8656         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8657         # LU-16904 Create plain layout files
8658         lfs setstripe -c 1 $dir/$tfile-{1..10}
8659
8660         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8661
8662         [[ $nfiles == 10 ]] ||
8663                 error "lfs find -E 1M found $nfiles != 10 files"
8664
8665         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8666         [[ $nfiles == 25 ]] ||
8667                 error "lfs find ! -E 1M found $nfiles != 25 files"
8668
8669         # All files have a component that starts at 0
8670         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8671         [[ $nfiles == 35 ]] ||
8672                 error "lfs find --component-start 0 - $nfiles != 35 files"
8673
8674         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8675         [[ $nfiles == 15 ]] ||
8676                 error "lfs find --component-start 2M - $nfiles != 15 files"
8677
8678         # All files created here have a componenet that does not starts at 2M
8679         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8680         [[ $nfiles == 35 ]] ||
8681                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8682
8683         # Find files with a specified number of components
8684         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8685         [[ $nfiles == 15 ]] ||
8686                 error "lfs find --component-count 3 - $nfiles != 15 files"
8687
8688         # Remember non-composite files have a component count of zero
8689         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8690         [[ $nfiles == 10 ]] ||
8691                 error "lfs find --component-count 0 - $nfiles != 10 files"
8692
8693         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8694         [[ $nfiles == 20 ]] ||
8695                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8696
8697         # All files have a flag called "init"
8698         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8699         [[ $nfiles == 35 ]] ||
8700                 error "lfs find --component-flags init - $nfiles != 35 files"
8701
8702         # Multi-component files will have a component not initialized
8703         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8704         [[ $nfiles == 15 ]] ||
8705                 error "lfs find !--component-flags init - $nfiles != 15 files"
8706
8707         rm -rf $dir
8708
8709 }
8710 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8711
8712 test_56ca() {
8713         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8714                 skip "Need MDS version at least 2.10.57"
8715
8716         local td=$DIR/$tdir
8717         local tf=$td/$tfile
8718         local dir
8719         local nfiles
8720         local cmd
8721         local i
8722         local j
8723
8724         # create mirrored directories and mirrored files
8725         mkdir $td || error "mkdir $td failed"
8726         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8727         createmany -o $tf- 10 || error "create $tf- failed"
8728
8729         for i in $(seq 2); do
8730                 dir=$td/dir$i
8731                 mkdir $dir || error "mkdir $dir failed"
8732                 $LFS mirror create -N$((3 + i)) $dir ||
8733                         error "create mirrored dir $dir failed"
8734                 createmany -o $dir/$tfile- 10 ||
8735                         error "create $dir/$tfile- failed"
8736         done
8737
8738         # change the states of some mirrored files
8739         echo foo > $tf-6
8740         for i in $(seq 2); do
8741                 dir=$td/dir$i
8742                 for j in $(seq 4 9); do
8743                         echo foo > $dir/$tfile-$j
8744                 done
8745         done
8746
8747         # find mirrored files with specific mirror count
8748         cmd="$LFS find --mirror-count 3 --type f $td"
8749         nfiles=$($cmd | wc -l)
8750         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8751
8752         cmd="$LFS find ! --mirror-count 3 --type f $td"
8753         nfiles=$($cmd | wc -l)
8754         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8755
8756         cmd="$LFS find --mirror-count +2 --type f $td"
8757         nfiles=$($cmd | wc -l)
8758         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8759
8760         cmd="$LFS find --mirror-count -6 --type f $td"
8761         nfiles=$($cmd | wc -l)
8762         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8763
8764         # find mirrored files with specific file state
8765         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8766         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8767
8768         cmd="$LFS find --mirror-state=ro --type f $td"
8769         nfiles=$($cmd | wc -l)
8770         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8771
8772         cmd="$LFS find ! --mirror-state=ro --type f $td"
8773         nfiles=$($cmd | wc -l)
8774         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8775
8776         cmd="$LFS find --mirror-state=wp --type f $td"
8777         nfiles=$($cmd | wc -l)
8778         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8779
8780         cmd="$LFS find ! --mirror-state=sp --type f $td"
8781         nfiles=$($cmd | wc -l)
8782         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8783 }
8784 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8785
8786 test_56da() { # LU-14179
8787         local path=$DIR/$tdir
8788
8789         test_mkdir $path
8790         cd $path
8791
8792         local longdir=$(str_repeat 'a' 255)
8793
8794         for i in {1..15}; do
8795                 path=$path/$longdir
8796                 test_mkdir $longdir
8797                 cd $longdir
8798         done
8799
8800         local len=${#path}
8801         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8802
8803         test_mkdir $lastdir
8804         cd $lastdir
8805         # PATH_MAX-1
8806         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8807
8808         # NAME_MAX
8809         touch $(str_repeat 'f' 255)
8810
8811         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8812                 error "lfs find reported an error"
8813
8814         rm -rf $DIR/$tdir
8815 }
8816 run_test 56da "test lfs find with long paths"
8817
8818 test_56ea() { #LU-10378
8819         local path=$DIR/$tdir
8820         local pool=$TESTNAME
8821
8822         # Create ost pool
8823         pool_add $pool || error "pool_add $pool failed"
8824         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8825                 error "adding targets to $pool failed"
8826
8827         # Set default pool on directory before creating file
8828         mkdir $path || error "mkdir $path failed"
8829         $LFS setstripe -p $pool $path ||
8830                 error "set OST pool on $pool failed"
8831         touch $path/$tfile || error "touch $path/$tfile failed"
8832
8833         # Compare basic file attributes from -printf and stat
8834         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8835         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8836
8837         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8838                 error "Attrs from lfs find and stat don't match"
8839
8840         # Compare Lustre attributes from lfs find and lfs getstripe
8841         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8842         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8843         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8844         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8845         local fpool=$($LFS getstripe --pool $path/$tfile)
8846         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8847
8848         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8849                 error "Attrs from lfs find and lfs getstripe don't match"
8850
8851         # Verify behavior for unknown escape/format sequences
8852         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8853
8854         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8855                 error "Escape/format codes don't match"
8856 }
8857 run_test 56ea "test lfs find -printf option"
8858
8859 test_56eb() {
8860         local dir=$DIR/$tdir
8861         local subdir_1=$dir/subdir_1
8862
8863         test_mkdir -p $subdir_1
8864         ln -s subdir_1 $dir/link_1
8865
8866         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8867                 error "symlink is not followed"
8868
8869         $LFS getstripe --no-follow $dir |
8870                 grep "^$dir/link_1 has no stripe info$" ||
8871                 error "symlink should not have stripe info"
8872
8873         touch $dir/testfile
8874         ln -s testfile $dir/file_link_2
8875
8876         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8877                 error "symlink is not followed"
8878
8879         $LFS getstripe --no-follow $dir |
8880                 grep "^$dir/file_link_2 has no stripe info$" ||
8881                 error "symlink should not have stripe info"
8882 }
8883 run_test 56eb "check lfs getstripe on symlink"
8884
8885 test_56ec() {
8886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8887         local dir=$DIR/$tdir
8888         local srcfile=$dir/srcfile
8889         local srcyaml=$dir/srcyaml
8890         local destfile=$dir/destfile
8891
8892         test_mkdir -p $dir
8893
8894         $LFS setstripe -i 1 $srcfile
8895         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8896         # if the setstripe yaml parsing fails for any reason, the command can
8897         # randomly assign the correct OST index, leading to an erroneous
8898         # success. but the chance of false success is low enough that a
8899         # regression should still be quickly caught.
8900         $LFS setstripe --yaml=$srcyaml $destfile
8901
8902         local srcindex=$($LFS getstripe -i $srcfile)
8903         local destindex=$($LFS getstripe -i $destfile)
8904
8905         if [[ ! $srcindex -eq $destindex ]]; then
8906                 error "setstripe did not set OST index correctly"
8907         fi
8908 }
8909 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8910
8911 test_56eda() {
8912         local dir=$DIR/$tdir
8913         local subdir=$dir/subdir
8914         local file1=$dir/$tfile
8915         local file2=$dir/$tfile\2
8916         local link=$dir/$tfile-link
8917         local nfiles
8918
8919         test_mkdir -p $dir
8920         $LFS setdirstripe -c1 $subdir
8921         touch $file1
8922         touch $file2
8923         ln $file2 $link
8924
8925         nfiles=$($LFS find --links 1 $dir | wc -l)
8926         (( $nfiles == 1 )) ||
8927                 error "lfs find --links expected 1 file, got $nfiles"
8928
8929         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8930         (( $nfiles == 2 )) ||
8931                 error "lfs find --links expected 2 files, got $nfiles"
8932
8933         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8934         (( $nfiles == 1 )) ||
8935                 error "lfs find --links expected 1 directory, got $nfiles"
8936 }
8937 run_test 56eda "check lfs find --links"
8938
8939 test_56edb() {
8940         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8941
8942         local dir=$DIR/$tdir
8943         local stripedir=$dir/stripedir
8944         local nfiles
8945
8946         test_mkdir -p $dir
8947
8948         $LFS setdirstripe -c2 $stripedir
8949
8950         $LFS getdirstripe $stripedir
8951
8952         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8953         (( $nfiles == 1 )) ||
8954                 error "lfs find --links expected 1 directory, got $nfiles"
8955 }
8956 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8957
8958 test_56ef() {
8959         local dir=$DIR/$tdir
8960         local dir1=$dir/d1
8961         local dir2=$dir/d2
8962         local nfiles
8963
8964         test_mkdir -p $dir
8965
8966         mkdir $dir1
8967         mkdir $dir2
8968
8969         touch $dir1/f
8970         touch $dir2/f
8971
8972         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8973         (( $nfiles == 2 )) ||
8974                 error "(1) lfs find expected 2 files, got $nfiles"
8975
8976         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8977         (( $nfiles == 2 )) ||
8978                 error "(2) lfs find expected 2 files, got $nfiles"
8979
8980         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8981         (( $nfiles == 2 )) ||
8982                 error "(3) lfs find expected 2 files, got $nfiles"
8983 }
8984 run_test 56ef "lfs find with multiple paths"
8985
8986 test_57a() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         # note test will not do anything if MDS is not local
8989         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8990                 skip_env "ldiskfs only test"
8991         fi
8992         remote_mds_nodsh && skip "remote MDS with nodsh"
8993
8994         local MNTDEV="osd*.*MDT*.mntdev"
8995         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8996         [ -z "$DEV" ] && error "can't access $MNTDEV"
8997         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8998                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8999                         error "can't access $DEV"
9000                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9001                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9002                 rm $TMP/t57a.dump
9003         done
9004 }
9005 run_test 57a "verify MDS filesystem created with large inodes =="
9006
9007 test_57b() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9010                 skip_env "ldiskfs only test"
9011         fi
9012         remote_mds_nodsh && skip "remote MDS with nodsh"
9013
9014         local dir=$DIR/$tdir
9015         local filecount=100
9016         local file1=$dir/f1
9017         local fileN=$dir/f$filecount
9018
9019         rm -rf $dir || error "removing $dir"
9020         test_mkdir -c1 $dir
9021         local mdtidx=$($LFS getstripe -m $dir)
9022         local mdtname=MDT$(printf %04x $mdtidx)
9023         local facet=mds$((mdtidx + 1))
9024
9025         echo "mcreating $filecount files"
9026         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9027
9028         # verify that files do not have EAs yet
9029         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9030                 error "$file1 has an EA"
9031         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9032                 error "$fileN has an EA"
9033
9034         sync
9035         sleep 1
9036         df $dir  #make sure we get new statfs data
9037         local mdsfree=$(do_facet $facet \
9038                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9039         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9040         local file
9041
9042         echo "opening files to create objects/EAs"
9043         for file in $(seq -f $dir/f%g 1 $filecount); do
9044                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9045                         error "opening $file"
9046         done
9047
9048         # verify that files have EAs now
9049         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9050                 error "$file1 missing EA"
9051         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9052                 error "$fileN missing EA"
9053
9054         sleep 1  #make sure we get new statfs data
9055         df $dir
9056         local mdsfree2=$(do_facet $facet \
9057                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9058         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9059
9060         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9061                 if [ "$mdsfree" != "$mdsfree2" ]; then
9062                         error "MDC before $mdcfree != after $mdcfree2"
9063                 else
9064                         echo "MDC before $mdcfree != after $mdcfree2"
9065                         echo "unable to confirm if MDS has large inodes"
9066                 fi
9067         fi
9068         rm -rf $dir
9069 }
9070 run_test 57b "default LOV EAs are stored inside large inodes ==="
9071
9072 test_58() {
9073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9074         [ -z "$(which wiretest 2>/dev/null)" ] &&
9075                         skip_env "could not find wiretest"
9076
9077         wiretest
9078 }
9079 run_test 58 "verify cross-platform wire constants =============="
9080
9081 test_59() {
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083
9084         echo "touch 130 files"
9085         createmany -o $DIR/f59- 130
9086         echo "rm 130 files"
9087         unlinkmany $DIR/f59- 130
9088         sync
9089         # wait for commitment of removal
9090         wait_delete_completed
9091 }
9092 run_test 59 "verify cancellation of llog records async ========="
9093
9094 TEST60_HEAD="test_60 run $RANDOM"
9095 test_60a() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         remote_mgs_nodsh && skip "remote MGS with nodsh"
9098         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9099                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9100                         skip_env "missing subtest run-llog.sh"
9101
9102         log "$TEST60_HEAD - from kernel mode"
9103         do_facet mgs "$LCTL dk > /dev/null"
9104         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9105         do_facet mgs $LCTL dk > $TMP/$tfile
9106
9107         # LU-6388: test llog_reader
9108         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9109         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9110         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9111                         skip_env "missing llog_reader"
9112         local fstype=$(facet_fstype mgs)
9113         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9114                 skip_env "Only for ldiskfs or zfs type mgs"
9115
9116         local mntpt=$(facet_mntpt mgs)
9117         local mgsdev=$(mgsdevname 1)
9118         local fid_list
9119         local fid
9120         local rec_list
9121         local rec
9122         local rec_type
9123         local obj_file
9124         local path
9125         local seq
9126         local oid
9127         local pass=true
9128
9129         #get fid and record list
9130         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9131                 tail -n 4))
9132         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9133                 tail -n 4))
9134         #remount mgs as ldiskfs or zfs type
9135         stop mgs || error "stop mgs failed"
9136         mount_fstype mgs || error "remount mgs failed"
9137         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9138                 fid=${fid_list[i]}
9139                 rec=${rec_list[i]}
9140                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9141                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9142                 oid=$((16#$oid))
9143
9144                 case $fstype in
9145                         ldiskfs )
9146                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9147                         zfs )
9148                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9149                 esac
9150                 echo "obj_file is $obj_file"
9151                 do_facet mgs $llog_reader $obj_file
9152
9153                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9154                         awk '{ print $3 }' | sed -e "s/^type=//g")
9155                 if [ $rec_type != $rec ]; then
9156                         echo "FAILED test_60a wrong record type $rec_type," \
9157                               "should be $rec"
9158                         pass=false
9159                         break
9160                 fi
9161
9162                 #check obj path if record type is LLOG_LOGID_MAGIC
9163                 if [ "$rec" == "1064553b" ]; then
9164                         path=$(do_facet mgs $llog_reader $obj_file |
9165                                 grep "path=" | awk '{ print $NF }' |
9166                                 sed -e "s/^path=//g")
9167                         if [ $obj_file != $mntpt/$path ]; then
9168                                 echo "FAILED test_60a wrong obj path" \
9169                                       "$montpt/$path, should be $obj_file"
9170                                 pass=false
9171                                 break
9172                         fi
9173                 fi
9174         done
9175         rm -f $TMP/$tfile
9176         #restart mgs before "error", otherwise it will block the next test
9177         stop mgs || error "stop mgs failed"
9178         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9179         $pass || error "test failed, see FAILED test_60a messages for specifics"
9180 }
9181 run_test 60a "llog_test run from kernel module and test llog_reader"
9182
9183 test_60b() { # bug 6411
9184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9185
9186         dmesg > $DIR/$tfile
9187         LLOG_COUNT=$(do_facet mgs dmesg |
9188                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9189                           /llog_[a-z]*.c:[0-9]/ {
9190                                 if (marker)
9191                                         from_marker++
9192                                 from_begin++
9193                           }
9194                           END {
9195                                 if (marker)
9196                                         print from_marker
9197                                 else
9198                                         print from_begin
9199                           }")
9200
9201         [[ $LLOG_COUNT -gt 120 ]] &&
9202                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9203 }
9204 run_test 60b "limit repeated messages from CERROR/CWARN"
9205
9206 test_60c() {
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208
9209         echo "create 5000 files"
9210         createmany -o $DIR/f60c- 5000
9211 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9212         lctl set_param fail_loc=0x80000137
9213         unlinkmany $DIR/f60c- 5000
9214         lctl set_param fail_loc=0
9215 }
9216 run_test 60c "unlink file when mds full"
9217
9218 test_60d() {
9219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9220
9221         SAVEPRINTK=$(lctl get_param -n printk)
9222         # verify "lctl mark" is even working"
9223         MESSAGE="test message ID $RANDOM $$"
9224         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9225         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9226
9227         lctl set_param printk=0 || error "set lnet.printk failed"
9228         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9229         MESSAGE="new test message ID $RANDOM $$"
9230         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9231         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9232         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9233
9234         lctl set_param -n printk="$SAVEPRINTK"
9235 }
9236 run_test 60d "test printk console message masking"
9237
9238 test_60e() {
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240         remote_mds_nodsh && skip "remote MDS with nodsh"
9241
9242         touch $DIR/$tfile
9243 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9244         do_facet mds1 lctl set_param fail_loc=0x15b
9245         rm $DIR/$tfile
9246 }
9247 run_test 60e "no space while new llog is being created"
9248
9249 test_60f() {
9250         local old_path=$($LCTL get_param -n debug_path)
9251
9252         stack_trap "$LCTL set_param debug_path=$old_path"
9253         stack_trap "rm -f $TMP/$tfile*"
9254         rm -f $TMP/$tfile* 2> /dev/null
9255         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9256         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9257         test_mkdir $DIR/$tdir
9258         # retry in case the open is cached and not released
9259         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9260                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9261                 sleep 0.1
9262         done
9263         ls $TMP/$tfile*
9264         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9265 }
9266 run_test 60f "change debug_path works"
9267
9268 test_60g() {
9269         local pid
9270         local i
9271
9272         test_mkdir -c $MDSCOUNT $DIR/$tdir
9273
9274         (
9275                 local index=0
9276                 while true; do
9277                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9278                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9279                                 2>/dev/null
9280                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9281                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9282                         index=$((index + 1))
9283                 done
9284         ) &
9285
9286         pid=$!
9287
9288         for i in {0..100}; do
9289                 # define OBD_FAIL_OSD_TXN_START    0x19a
9290                 local index=$((i % MDSCOUNT + 1))
9291
9292                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9293                         > /dev/null
9294                 sleep 0.01
9295         done
9296
9297         kill -9 $pid
9298
9299         for i in $(seq $MDSCOUNT); do
9300                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9301         done
9302
9303         mkdir $DIR/$tdir/new || error "mkdir failed"
9304         rmdir $DIR/$tdir/new || error "rmdir failed"
9305
9306         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9307                 -t namespace
9308         for i in $(seq $MDSCOUNT); do
9309                 wait_update_facet mds$i "$LCTL get_param -n \
9310                         mdd.$(facet_svc mds$i).lfsck_namespace |
9311                         awk '/^status/ { print \\\$2 }'" "completed"
9312         done
9313
9314         ls -R $DIR/$tdir
9315         rm -rf $DIR/$tdir || error "rmdir failed"
9316 }
9317 run_test 60g "transaction abort won't cause MDT hung"
9318
9319 test_60h() {
9320         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9321                 skip "Need MDS version at least 2.12.52"
9322         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9323
9324         local f
9325
9326         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9327         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9328         for fail_loc in 0x80000188 0x80000189; do
9329                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9330                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9331                         error "mkdir $dir-$fail_loc failed"
9332                 for i in {0..10}; do
9333                         # create may fail on missing stripe
9334                         echo $i > $DIR/$tdir-$fail_loc/$i
9335                 done
9336                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9337                         error "getdirstripe $tdir-$fail_loc failed"
9338                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9339                         error "migrate $tdir-$fail_loc failed"
9340                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9341                         error "getdirstripe $tdir-$fail_loc failed"
9342                 pushd $DIR/$tdir-$fail_loc
9343                 for f in *; do
9344                         echo $f | cmp $f - || error "$f data mismatch"
9345                 done
9346                 popd
9347                 rm -rf $DIR/$tdir-$fail_loc
9348         done
9349 }
9350 run_test 60h "striped directory with missing stripes can be accessed"
9351
9352 function t60i_load() {
9353         mkdir $DIR/$tdir
9354         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9355         $LCTL set_param fail_loc=0x131c fail_val=1
9356         for ((i=0; i<5000; i++)); do
9357                 touch $DIR/$tdir/f$i
9358         done
9359 }
9360
9361 test_60i() {
9362         changelog_register || error "changelog_register failed"
9363         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9364         changelog_users $SINGLEMDS | grep -q $cl_user ||
9365                 error "User $cl_user not found in changelog_users"
9366         changelog_chmask "ALL"
9367         t60i_load &
9368         local PID=$!
9369         for((i=0; i<100; i++)); do
9370                 changelog_dump >/dev/null ||
9371                         error "can't read changelog"
9372         done
9373         kill $PID
9374         wait $PID
9375         changelog_deregister || error "changelog_deregister failed"
9376         $LCTL set_param fail_loc=0
9377 }
9378 run_test 60i "llog: new record vs reader race"
9379
9380 test_60j() {
9381         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9382                 skip "need MDS version at least 2.15.50"
9383         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9384         remote_mds_nodsh && skip "remote MDS with nodsh"
9385         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9386
9387         changelog_users $SINGLEMDS | grep "^cl" &&
9388                 skip "active changelog user"
9389
9390         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9391
9392         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9393                 skip_env "missing llog_reader"
9394
9395         mkdir_on_mdt0 $DIR/$tdir
9396
9397         local f=$DIR/$tdir/$tfile
9398         local mdt_dev
9399         local tmpfile
9400         local plain
9401
9402         changelog_register || error "cannot register changelog user"
9403
9404         # set changelog_mask to ALL
9405         changelog_chmask "ALL"
9406         changelog_clear
9407
9408         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9409         unlinkmany ${f}- 100 || error "unlinkmany failed"
9410
9411         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9412         mdt_dev=$(facet_device $SINGLEMDS)
9413
9414         do_facet $SINGLEMDS sync
9415         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9416                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9417                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9418
9419         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9420
9421         # if $tmpfile is not on EXT3 filesystem for some reason
9422         [[ ${plain:0:1} == 'O' ]] ||
9423                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9424
9425         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9426                 $mdt_dev; stat -c %s $tmpfile")
9427         echo "Truncate llog from $size to $((size - size % 8192))"
9428         size=$((size - size % 8192))
9429         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9430         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9431                 grep -c 'in bitmap only')
9432         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9433
9434         size=$((size - 9000))
9435         echo "Corrupt llog in the middle at $size"
9436         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9437                 count=333 conv=notrunc
9438         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9439                 grep -c 'next chunk')
9440         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9441 }
9442 run_test 60j "llog_reader reports corruptions"
9443
9444 test_61a() {
9445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9446
9447         f="$DIR/f61"
9448         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9449         cancel_lru_locks osc
9450         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9451         sync
9452 }
9453 run_test 61a "mmap() writes don't make sync hang ================"
9454
9455 test_61b() {
9456         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9457 }
9458 run_test 61b "mmap() of unstriped file is successful"
9459
9460 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9461 # Though this test is irrelevant anymore, it helped to reveal some
9462 # other grant bugs (LU-4482), let's keep it.
9463 test_63a() {   # was test_63
9464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9465
9466         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9467
9468         for i in `seq 10` ; do
9469                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9470                 sleep 5
9471                 kill $!
9472                 sleep 1
9473         done
9474
9475         rm -f $DIR/f63 || true
9476 }
9477 run_test 63a "Verify oig_wait interruption does not crash ======="
9478
9479 # bug 2248 - async write errors didn't return to application on sync
9480 # bug 3677 - async write errors left page locked
9481 test_63b() {
9482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9483
9484         debugsave
9485         lctl set_param debug=-1
9486
9487         # ensure we have a grant to do async writes
9488         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9489         rm $DIR/$tfile
9490
9491         sync    # sync lest earlier test intercept the fail_loc
9492
9493         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9494         lctl set_param fail_loc=0x80000406
9495         $MULTIOP $DIR/$tfile Owy && \
9496                 error "sync didn't return ENOMEM"
9497         sync; sleep 2; sync     # do a real sync this time to flush page
9498         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9499                 error "locked page left in cache after async error" || true
9500         debugrestore
9501 }
9502 run_test 63b "async write errors should be returned to fsync ==="
9503
9504 test_64a () {
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506
9507         lfs df $DIR
9508         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9509 }
9510 run_test 64a "verify filter grant calculations (in kernel) ====="
9511
9512 test_64b () {
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514
9515         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9516 }
9517 run_test 64b "check out-of-space detection on client"
9518
9519 test_64c() {
9520         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9521 }
9522 run_test 64c "verify grant shrink"
9523
9524 import_param() {
9525         local tgt=$1
9526         local param=$2
9527
9528         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9529 }
9530
9531 # this does exactly what osc_request.c:osc_announce_cached() does in
9532 # order to calculate max amount of grants to ask from server
9533 want_grant() {
9534         local tgt=$1
9535
9536         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9537         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9538
9539         ((rpc_in_flight++));
9540         nrpages=$((nrpages * rpc_in_flight))
9541
9542         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9543
9544         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9545
9546         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9547         local undirty=$((nrpages * PAGE_SIZE))
9548
9549         local max_extent_pages
9550         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9551         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9552         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9553         local grant_extent_tax
9554         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9555
9556         undirty=$((undirty + nrextents * grant_extent_tax))
9557
9558         echo $undirty
9559 }
9560
9561 # this is size of unit for grant allocation. It should be equal to
9562 # what tgt_grant.c:tgt_grant_chunk() calculates
9563 grant_chunk() {
9564         local tgt=$1
9565         local max_brw_size
9566         local grant_extent_tax
9567
9568         max_brw_size=$(import_param $tgt max_brw_size)
9569
9570         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9571
9572         echo $(((max_brw_size + grant_extent_tax) * 2))
9573 }
9574
9575 test_64d() {
9576         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9577                 skip "OST < 2.10.55 doesn't limit grants enough"
9578
9579         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9580
9581         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9582                 skip "no grant_param connect flag"
9583
9584         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9585
9586         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9587         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9588
9589
9590         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9591         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9592
9593         $LFS setstripe $DIR/$tfile -i 0 -c 1
9594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9595         ddpid=$!
9596
9597         while kill -0 $ddpid; do
9598                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9599
9600                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9601                         kill $ddpid
9602                         error "cur_grant $cur_grant > $max_cur_granted"
9603                 fi
9604
9605                 sleep 1
9606         done
9607 }
9608 run_test 64d "check grant limit exceed"
9609
9610 check_grants() {
9611         local tgt=$1
9612         local expected=$2
9613         local msg=$3
9614         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9615
9616         ((cur_grants == expected)) ||
9617                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9618 }
9619
9620 round_up_p2() {
9621         echo $((($1 + $2 - 1) & ~($2 - 1)))
9622 }
9623
9624 test_64e() {
9625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9626         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9627                 skip "Need OSS version at least 2.11.56"
9628
9629         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9630         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9631         $LCTL set_param debug=+cache
9632
9633         # Remount client to reset grant
9634         remount_client $MOUNT || error "failed to remount client"
9635         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9636
9637         local init_grants=$(import_param $osc_tgt initial_grant)
9638
9639         check_grants $osc_tgt $init_grants "init grants"
9640
9641         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9642         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9643         local gbs=$(import_param $osc_tgt grant_block_size)
9644
9645         # write random number of bytes from max_brw_size / 4 to max_brw_size
9646         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9647         # align for direct io
9648         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9649         # round to grant consumption unit
9650         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9651
9652         local grants=$((wb_round_up + extent_tax))
9653
9654         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9655         stack_trap "rm -f $DIR/$tfile"
9656
9657         # define OBD_FAIL_TGT_NO_GRANT 0x725
9658         # make the server not grant more back
9659         do_facet ost1 $LCTL set_param fail_loc=0x725
9660         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9661
9662         do_facet ost1 $LCTL set_param fail_loc=0
9663
9664         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9665
9666         rm -f $DIR/$tfile || error "rm failed"
9667
9668         # Remount client to reset grant
9669         remount_client $MOUNT || error "failed to remount client"
9670         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9671
9672         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9673
9674         # define OBD_FAIL_TGT_NO_GRANT 0x725
9675         # make the server not grant more back
9676         do_facet ost1 $LCTL set_param fail_loc=0x725
9677         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9678         do_facet ost1 $LCTL set_param fail_loc=0
9679
9680         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9681 }
9682 run_test 64e "check grant consumption (no grant allocation)"
9683
9684 test_64f() {
9685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9686
9687         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9688         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9689         $LCTL set_param debug=+cache
9690
9691         # Remount client to reset grant
9692         remount_client $MOUNT || error "failed to remount client"
9693         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9694
9695         local init_grants=$(import_param $osc_tgt initial_grant)
9696         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9697         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9698         local gbs=$(import_param $osc_tgt grant_block_size)
9699         local chunk=$(grant_chunk $osc_tgt)
9700
9701         # write random number of bytes from max_brw_size / 4 to max_brw_size
9702         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9703         # align for direct io
9704         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9705         # round to grant consumption unit
9706         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9707
9708         local grants=$((wb_round_up + extent_tax))
9709
9710         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9711         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9712                 error "error writing to $DIR/$tfile"
9713
9714         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9715                 "direct io with grant allocation"
9716
9717         rm -f $DIR/$tfile || error "rm failed"
9718
9719         # Remount client to reset grant
9720         remount_client $MOUNT || error "failed to remount client"
9721         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9722
9723         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9724
9725         # Testing that buffered IO consumes grant on the client
9726
9727         # Delay the RPC on the server so it's guaranteed to not complete even
9728         # if the RPC is sent from the client
9729         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9730         $LCTL set_param fail_loc=0x50a fail_val=3
9731         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9732                 error "error writing to $DIR/$tfile with buffered IO"
9733
9734         check_grants $osc_tgt $((init_grants - grants)) \
9735                 "buffered io, not write rpc"
9736
9737         # Clear the fail loc and do a sync on the client
9738         $LCTL set_param fail_loc=0 fail_val=0
9739         sync
9740
9741         # RPC is now known to have sent
9742         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9743                 "buffered io, one RPC"
9744 }
9745 run_test 64f "check grant consumption (with grant allocation)"
9746
9747 test_64g() {
9748         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9749                 skip "Need MDS version at least 2.14.56"
9750
9751         local mdts=$(comma_list $(mdts_nodes))
9752
9753         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9754                         tr '\n' ' ')
9755         stack_trap "$LCTL set_param $old"
9756
9757         # generate dirty pages and increase dirty granted on MDT
9758         stack_trap "rm -f $DIR/$tfile-*"
9759         for (( i = 0; i < 10; i++)); do
9760                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9761                         error "can't set stripe"
9762                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9763                         error "can't dd"
9764                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9765                         $LFS getstripe $DIR/$tfile-$i
9766                         error "not DoM file"
9767                 }
9768         done
9769
9770         # flush dirty pages
9771         sync
9772
9773         # wait until grant shrink reset grant dirty on MDTs
9774         for ((i = 0; i < 120; i++)); do
9775                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9776                         awk '{sum=sum+$1} END {print sum}')
9777                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9778                 echo "$grant_dirty grants, $vm_dirty pages"
9779                 (( grant_dirty + vm_dirty == 0 )) && break
9780                 (( i == 3 )) && sync &&
9781                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9782                 sleep 1
9783         done
9784
9785         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9786                 awk '{sum=sum+$1} END {print sum}')
9787         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9788 }
9789 run_test 64g "grant shrink on MDT"
9790
9791 test_64h() {
9792         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9793                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9794
9795         local instance=$($LFS getname -i $DIR)
9796         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9797         local num_exps=$(do_facet ost1 \
9798             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9799         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9800         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9801         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9802
9803         # 10MiB is for file to be written, max_brw_size * 16 *
9804         # num_exps is space reserve so that tgt_grant_shrink() decided
9805         # to not shrink
9806         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9807         (( avail * 1024 < expect )) &&
9808                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9809
9810         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9811         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9812         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9813         $LCTL set_param osc.*OST0000*.grant_shrink=1
9814         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9815
9816         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9817         stack_trap "rm -f $DIR/$tfile"
9818         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9819
9820         # drop cache so that coming read would do rpc
9821         cancel_lru_locks osc
9822
9823         # shrink interval is set to 10, pause for 7 seconds so that
9824         # grant thread did not wake up yet but coming read entered
9825         # shrink mode for rpc (osc_should_shrink_grant())
9826         sleep 7
9827
9828         declare -a cur_grant_bytes
9829         declare -a tot_granted
9830         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9831         tot_granted[0]=$(do_facet ost1 \
9832             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9833
9834         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9835
9836         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9837         tot_granted[1]=$(do_facet ost1 \
9838             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9839
9840         # grant change should be equal on both sides
9841         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9842                 tot_granted[0] - tot_granted[1])) ||
9843                 error "grant change mismatch, "                                \
9844                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9845                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9846 }
9847 run_test 64h "grant shrink on read"
9848
9849 test_64i() {
9850         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9851                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9852
9853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9854         remote_ost_nodsh && skip "remote OSTs with nodsh"
9855
9856         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9857         stack_trap "rm -f $DIR/$tfile"
9858
9859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9860
9861         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9862         local instance=$($LFS getname -i $DIR)
9863
9864         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9865         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9866
9867         # shrink grants and simulate rpc loss
9868         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9869         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9870         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9871
9872         fail ost1
9873
9874         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9875
9876         local testid=$(echo $TESTNAME | tr '_' ' ')
9877
9878         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9879                 grep "GRANT, real grant" &&
9880                 error "client has more grants then it owns" || true
9881 }
9882 run_test 64i "shrink on reconnect"
9883
9884 # bug 1414 - set/get directories' stripe info
9885 test_65a() {
9886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9887
9888         test_mkdir $DIR/$tdir
9889         touch $DIR/$tdir/f1
9890         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9891 }
9892 run_test 65a "directory with no stripe info"
9893
9894 test_65b() {
9895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9896
9897         test_mkdir $DIR/$tdir
9898         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9899
9900         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9901                                                 error "setstripe"
9902         touch $DIR/$tdir/f2
9903         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9904 }
9905 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9906
9907 test_65c() {
9908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9909         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9910
9911         test_mkdir $DIR/$tdir
9912         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9913
9914         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9915                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9916         touch $DIR/$tdir/f3
9917         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9918 }
9919 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9920
9921 test_65d() {
9922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9923
9924         test_mkdir $DIR/$tdir
9925         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9926         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9927
9928         if [[ $STRIPECOUNT -le 0 ]]; then
9929                 sc=1
9930         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9931                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9932                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9933         else
9934                 sc=$(($STRIPECOUNT - 1))
9935         fi
9936         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9937         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9938         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9939                 error "lverify failed"
9940 }
9941 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9942
9943 test_65e() {
9944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9945
9946         # LU-16904 delete layout when root is set as PFL layout
9947         save_layout_restore_at_exit $MOUNT
9948         $LFS setstripe -d $MOUNT || error "setstripe failed"
9949
9950         test_mkdir $DIR/$tdir
9951
9952         $LFS setstripe $DIR/$tdir || error "setstripe"
9953         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9954                                         error "no stripe info failed"
9955         touch $DIR/$tdir/f6
9956         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9957 }
9958 run_test 65e "directory setstripe defaults"
9959
9960 test_65f() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962
9963         test_mkdir $DIR/${tdir}f
9964         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9965                 error "setstripe succeeded" || true
9966 }
9967 run_test 65f "dir setstripe permission (should return error) ==="
9968
9969 test_65g() {
9970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9971
9972         # LU-16904 delete layout when root is set as PFL layout
9973         save_layout_restore_at_exit $MOUNT
9974         $LFS setstripe -d $MOUNT || error "setstripe failed"
9975
9976         test_mkdir $DIR/$tdir
9977         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9978
9979         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9980                 error "setstripe -S failed"
9981         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9982         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9983                 error "delete default stripe failed"
9984 }
9985 run_test 65g "directory setstripe -d"
9986
9987 test_65h() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989
9990         test_mkdir $DIR/$tdir
9991         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9992
9993         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9994                 error "setstripe -S failed"
9995         test_mkdir $DIR/$tdir/dd1
9996         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9997                 error "stripe info inherit failed"
9998 }
9999 run_test 65h "directory stripe info inherit ===================="
10000
10001 test_65i() {
10002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10003
10004         save_layout_restore_at_exit $MOUNT
10005
10006         # bug6367: set non-default striping on root directory
10007         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10008
10009         # bug12836: getstripe on -1 default directory striping
10010         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10011
10012         # bug12836: getstripe -v on -1 default directory striping
10013         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10014
10015         # bug12836: new find on -1 default directory striping
10016         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10017 }
10018 run_test 65i "various tests to set root directory striping"
10019
10020 test_65j() { # bug6367
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022
10023         sync; sleep 1
10024
10025         # if we aren't already remounting for each test, do so for this test
10026         if [ "$I_MOUNTED" = "yes" ]; then
10027                 cleanup || error "failed to unmount"
10028                 setup
10029         fi
10030
10031         save_layout_restore_at_exit $MOUNT
10032
10033         $LFS setstripe -d $MOUNT || error "setstripe failed"
10034 }
10035 run_test 65j "set default striping on root directory (bug 6367)="
10036
10037 cleanup_65k() {
10038         rm -rf $DIR/$tdir
10039         wait_delete_completed
10040         do_facet $SINGLEMDS "lctl set_param -n \
10041                 osp.$ost*MDT0000.max_create_count=$max_count"
10042         do_facet $SINGLEMDS "lctl set_param -n \
10043                 osp.$ost*MDT0000.create_count=$count"
10044         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10045         echo $INACTIVE_OSC "is Activate"
10046
10047         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10048 }
10049
10050 test_65k() { # bug11679
10051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10052         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10053         remote_mds_nodsh && skip "remote MDS with nodsh"
10054
10055         local disable_precreate=true
10056         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10057                 disable_precreate=false
10058
10059         echo "Check OST status: "
10060         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10061                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10062
10063         for OSC in $MDS_OSCS; do
10064                 echo $OSC "is active"
10065                 do_facet $SINGLEMDS lctl --device %$OSC activate
10066         done
10067
10068         for INACTIVE_OSC in $MDS_OSCS; do
10069                 local ost=$(osc_to_ost $INACTIVE_OSC)
10070                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10071                                lov.*md*.target_obd |
10072                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10073
10074                 mkdir -p $DIR/$tdir
10075                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10076                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10077
10078                 echo "Deactivate: " $INACTIVE_OSC
10079                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10080
10081                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10082                               osp.$ost*MDT0000.create_count")
10083                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10084                                   osp.$ost*MDT0000.max_create_count")
10085                 $disable_precreate &&
10086                         do_facet $SINGLEMDS "lctl set_param -n \
10087                                 osp.$ost*MDT0000.max_create_count=0"
10088
10089                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10090                         [ -f $DIR/$tdir/$idx ] && continue
10091                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10092                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10093                                 { cleanup_65k;
10094                                   error "setstripe $idx should succeed"; }
10095                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10096                 done
10097                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10098                 rmdir $DIR/$tdir
10099
10100                 do_facet $SINGLEMDS "lctl set_param -n \
10101                         osp.$ost*MDT0000.max_create_count=$max_count"
10102                 do_facet $SINGLEMDS "lctl set_param -n \
10103                         osp.$ost*MDT0000.create_count=$count"
10104                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10105                 echo $INACTIVE_OSC "is Activate"
10106
10107                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10108         done
10109 }
10110 run_test 65k "validate manual striping works properly with deactivated OSCs"
10111
10112 test_65l() { # bug 12836
10113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10114
10115         test_mkdir -p $DIR/$tdir/test_dir
10116         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10117         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10118 }
10119 run_test 65l "lfs find on -1 stripe dir ========================"
10120
10121 test_65m() {
10122         local layout=$(save_layout $MOUNT)
10123         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10124                 restore_layout $MOUNT $layout
10125                 error "setstripe should fail by non-root users"
10126         }
10127         true
10128 }
10129 run_test 65m "normal user can't set filesystem default stripe"
10130
10131 test_65n() {
10132         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10133         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10134                 skip "Need MDS version at least 2.12.50"
10135         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10136
10137         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10138         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10139         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10140
10141         save_layout_restore_at_exit $MOUNT
10142
10143         # new subdirectory under root directory should not inherit
10144         # the default layout from root
10145         # LU-16904 check if the root is set as PFL layout
10146         local numcomp=$($LFS getstripe --component-count $MOUNT)
10147
10148         if [[ $numcomp -eq 0 ]]; then
10149                 local dir1=$MOUNT/$tdir-1
10150                 mkdir $dir1 || error "mkdir $dir1 failed"
10151                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10152                         error "$dir1 shouldn't have LOV EA"
10153         fi
10154
10155         # delete the default layout on root directory
10156         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10157
10158         local dir2=$MOUNT/$tdir-2
10159         mkdir $dir2 || error "mkdir $dir2 failed"
10160         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10161                 error "$dir2 shouldn't have LOV EA"
10162
10163         # set a new striping pattern on root directory
10164         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10165         local new_def_stripe_size=$((def_stripe_size * 2))
10166         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10167                 error "set stripe size on $MOUNT failed"
10168
10169         # new file created in $dir2 should inherit the new stripe size from
10170         # the filesystem default
10171         local file2=$dir2/$tfile-2
10172         touch $file2 || error "touch $file2 failed"
10173
10174         local file2_stripe_size=$($LFS getstripe -S $file2)
10175         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10176         {
10177                 echo "file2_stripe_size: '$file2_stripe_size'"
10178                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10179                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10180         }
10181
10182         local dir3=$MOUNT/$tdir-3
10183         mkdir $dir3 || error "mkdir $dir3 failed"
10184         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10185         # the root layout, which is the actual default layout that will be used
10186         # when new files are created in $dir3.
10187         local dir3_layout=$(get_layout_param $dir3)
10188         local root_dir_layout=$(get_layout_param $MOUNT)
10189         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10190         {
10191                 echo "dir3_layout: '$dir3_layout'"
10192                 echo "root_dir_layout: '$root_dir_layout'"
10193                 error "$dir3 should show the default layout from $MOUNT"
10194         }
10195
10196         # set OST pool on root directory
10197         local pool=$TESTNAME
10198         pool_add $pool || error "add $pool failed"
10199         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10200                 error "add targets to $pool failed"
10201
10202         $LFS setstripe -p $pool $MOUNT ||
10203                 error "set OST pool on $MOUNT failed"
10204
10205         # new file created in $dir3 should inherit the pool from
10206         # the filesystem default
10207         local file3=$dir3/$tfile-3
10208         touch $file3 || error "touch $file3 failed"
10209
10210         local file3_pool=$($LFS getstripe -p $file3)
10211         [[ "$file3_pool" = "$pool" ]] ||
10212                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10213
10214         local dir4=$MOUNT/$tdir-4
10215         mkdir $dir4 || error "mkdir $dir4 failed"
10216         local dir4_layout=$(get_layout_param $dir4)
10217         root_dir_layout=$(get_layout_param $MOUNT)
10218         echo "$LFS getstripe -d $dir4"
10219         $LFS getstripe -d $dir4
10220         echo "$LFS getstripe -d $MOUNT"
10221         $LFS getstripe -d $MOUNT
10222         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10223         {
10224                 echo "dir4_layout: '$dir4_layout'"
10225                 echo "root_dir_layout: '$root_dir_layout'"
10226                 error "$dir4 should show the default layout from $MOUNT"
10227         }
10228
10229         # new file created in $dir4 should inherit the pool from
10230         # the filesystem default
10231         local file4=$dir4/$tfile-4
10232         touch $file4 || error "touch $file4 failed"
10233
10234         local file4_pool=$($LFS getstripe -p $file4)
10235         [[ "$file4_pool" = "$pool" ]] ||
10236                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10237
10238         # new subdirectory under non-root directory should inherit
10239         # the default layout from its parent directory
10240         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10241                 error "set directory layout on $dir4 failed"
10242
10243         local dir5=$dir4/$tdir-5
10244         mkdir $dir5 || error "mkdir $dir5 failed"
10245
10246         dir4_layout=$(get_layout_param $dir4)
10247         local dir5_layout=$(get_layout_param $dir5)
10248         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10249         {
10250                 echo "dir4_layout: '$dir4_layout'"
10251                 echo "dir5_layout: '$dir5_layout'"
10252                 error "$dir5 should inherit the default layout from $dir4"
10253         }
10254
10255         # though subdir under ROOT doesn't inherit default layout, but
10256         # its sub dir/file should be created with default layout.
10257         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10258         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10259                 skip "Need MDS version at least 2.12.59"
10260
10261         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10262         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10263         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10264
10265         if [ $default_lmv_hash == "none" ]; then
10266                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10267         else
10268                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10269                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10270         fi
10271
10272         $LFS setdirstripe -D -c 2 $MOUNT ||
10273                 error "setdirstripe -D -c 2 failed"
10274         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10275         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10276         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10277
10278         # $dir4 layout includes pool
10279         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10280         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10281                 error "pool lost on setstripe"
10282         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10283         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10284                 error "pool lost on compound layout setstripe"
10285 }
10286 run_test 65n "don't inherit default layout from root for new subdirectories"
10287
10288 test_65o() {
10289         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10290                 skip "need MDS version at least 2.14.57"
10291
10292         # set OST pool on root directory
10293         local pool=$TESTNAME
10294
10295         pool_add $pool || error "add $pool failed"
10296         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10297                 error "add targets to $pool failed"
10298
10299         local dir1=$MOUNT/$tdir
10300
10301         mkdir $dir1 || error "mkdir $dir1 failed"
10302
10303         # set a new striping pattern on root directory
10304         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10305
10306         $LFS setstripe -p $pool $dir1 ||
10307                 error "set directory layout on $dir1 failed"
10308
10309         # $dir1 layout includes pool
10310         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10311         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10312                 error "pool lost on setstripe"
10313         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10314         $LFS getstripe $dir1
10315         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10316                 error "pool lost on compound layout setstripe"
10317
10318         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10319                 error "setdirstripe failed on sub-dir with inherited pool"
10320         $LFS getstripe $dir1/dir2
10321         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10322                 error "pool lost on compound layout setdirstripe"
10323
10324         $LFS setstripe -E -1 -c 1 $dir1
10325         $LFS getstripe -d $dir1
10326         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10327                 error "pool lost on setstripe"
10328 }
10329 run_test 65o "pool inheritance for mdt component"
10330
10331 test_65p () { # LU-16152
10332         local src_dir=$DIR/$tdir/src_dir
10333         local dst_dir=$DIR/$tdir/dst_dir
10334         local yaml_file=$DIR/$tdir/layout.yaml
10335         local border
10336
10337         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10338                 skip "Need at least version 2.15.51"
10339
10340         test_mkdir -p $src_dir
10341         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10342                 error "failed to setstripe"
10343         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10344                 error "failed to getstripe"
10345
10346         test_mkdir -p $dst_dir
10347         $LFS setstripe --yaml $yaml_file $dst_dir ||
10348                 error "failed to setstripe with yaml file"
10349         border=$($LFS getstripe -d $dst_dir |
10350                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10351                 error "failed to getstripe"
10352
10353         # 2048M is 0x80000000, or 2147483648
10354         (( $border == 2147483648 )) ||
10355                 error "failed to handle huge number in yaml layout"
10356 }
10357 run_test 65p "setstripe with yaml file and huge number"
10358
10359 test_65p () { # LU-16194
10360         local src_dir=$DIR/$tdir/src_dir
10361
10362         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10363                 skip "Need at least version 2.15.51"
10364
10365         test_mkdir -p $src_dir
10366         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10367         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10368                 error "should fail if extent start/end >=8E"
10369
10370         # EOF should work as before
10371         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10372                 error "failed to setstripe normally"
10373 }
10374 run_test 65p "setstripe with >=8E offset should fail"
10375
10376 # bug 2543 - update blocks count on client
10377 test_66() {
10378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10379
10380         local COUNT=${COUNT:-8}
10381         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10382         sync; sync_all_data; sync; sync_all_data
10383         cancel_lru_locks osc
10384         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10385         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10386 }
10387 run_test 66 "update inode blocks count on client ==============="
10388
10389 meminfo() {
10390         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10391 }
10392
10393 swap_used() {
10394         swapon -s | awk '($1 == "'$1'") { print $4 }'
10395 }
10396
10397 # bug5265, obdfilter oa2dentry return -ENOENT
10398 # #define OBD_FAIL_SRV_ENOENT 0x217
10399 test_69() {
10400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10401         remote_ost_nodsh && skip "remote OST with nodsh"
10402
10403         f="$DIR/$tfile"
10404         $LFS setstripe -c 1 -i 0 $f
10405         stack_trap "rm -f $f ${f}.2"
10406
10407         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10408
10409         do_facet ost1 lctl set_param fail_loc=0x217
10410         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10411         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10412
10413         do_facet ost1 lctl set_param fail_loc=0
10414         $DIRECTIO write $f 0 2 || error "write error"
10415
10416         cancel_lru_locks osc
10417         $DIRECTIO read $f 0 1 || error "read error"
10418
10419         do_facet ost1 lctl set_param fail_loc=0x217
10420         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10421
10422         do_facet ost1 lctl set_param fail_loc=0
10423 }
10424 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10425
10426 test_71() {
10427         test_mkdir $DIR/$tdir
10428         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10429         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10430 }
10431 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10432
10433 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10435         [ "$RUNAS_ID" = "$UID" ] &&
10436                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10437         # Check that testing environment is properly set up. Skip if not
10438         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10439                 skip_env "User $RUNAS_ID does not exist - skipping"
10440
10441         touch $DIR/$tfile
10442         chmod 777 $DIR/$tfile
10443         chmod ug+s $DIR/$tfile
10444         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10445                 error "$RUNAS dd $DIR/$tfile failed"
10446         # See if we are still setuid/sgid
10447         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10448                 error "S/gid is not dropped on write"
10449         # Now test that MDS is updated too
10450         cancel_lru_locks mdc
10451         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10452                 error "S/gid is not dropped on MDS"
10453         rm -f $DIR/$tfile
10454 }
10455 run_test 72a "Test that remove suid works properly (bug5695) ===="
10456
10457 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10458         local perm
10459
10460         [ "$RUNAS_ID" = "$UID" ] &&
10461                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10462         [ "$RUNAS_ID" -eq 0 ] &&
10463                 skip_env "RUNAS_ID = 0 -- skipping"
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465         # Check that testing environment is properly set up. Skip if not
10466         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10467                 skip_env "User $RUNAS_ID does not exist - skipping"
10468
10469         touch $DIR/${tfile}-f{g,u}
10470         test_mkdir $DIR/${tfile}-dg
10471         test_mkdir $DIR/${tfile}-du
10472         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10473         chmod g+s $DIR/${tfile}-{f,d}g
10474         chmod u+s $DIR/${tfile}-{f,d}u
10475         for perm in 777 2777 4777; do
10476                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10477                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10478                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10479                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10480         done
10481         true
10482 }
10483 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10484
10485 # bug 3462 - multiple simultaneous MDC requests
10486 test_73() {
10487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10488
10489         test_mkdir $DIR/d73-1
10490         test_mkdir $DIR/d73-2
10491         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10492         pid1=$!
10493
10494         lctl set_param fail_loc=0x80000129
10495         $MULTIOP $DIR/d73-1/f73-2 Oc &
10496         sleep 1
10497         lctl set_param fail_loc=0
10498
10499         $MULTIOP $DIR/d73-2/f73-3 Oc &
10500         pid3=$!
10501
10502         kill -USR1 $pid1
10503         wait $pid1 || return 1
10504
10505         sleep 25
10506
10507         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10508         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10509         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10510
10511         rm -rf $DIR/d73-*
10512 }
10513 run_test 73 "multiple MDC requests (should not deadlock)"
10514
10515 test_74a() { # bug 6149, 6184
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517
10518         touch $DIR/f74a
10519         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10520         #
10521         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10522         # will spin in a tight reconnection loop
10523         $LCTL set_param fail_loc=0x8000030e
10524         # get any lock that won't be difficult - lookup works.
10525         ls $DIR/f74a
10526         $LCTL set_param fail_loc=0
10527         rm -f $DIR/f74a
10528         true
10529 }
10530 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10531
10532 test_74b() { # bug 13310
10533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10534
10535         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10536         #
10537         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10538         # will spin in a tight reconnection loop
10539         $LCTL set_param fail_loc=0x8000030e
10540         # get a "difficult" lock
10541         touch $DIR/f74b
10542         $LCTL set_param fail_loc=0
10543         rm -f $DIR/f74b
10544         true
10545 }
10546 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10547
10548 test_74c() {
10549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10550
10551         #define OBD_FAIL_LDLM_NEW_LOCK
10552         $LCTL set_param fail_loc=0x319
10553         touch $DIR/$tfile && error "touch successful"
10554         $LCTL set_param fail_loc=0
10555         true
10556 }
10557 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10558
10559 slab_lic=/sys/kernel/slab/lustre_inode_cache
10560 num_objects() {
10561         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10562         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10563                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10564 }
10565
10566 test_76a() { # Now for b=20433, added originally in b=1443
10567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10568
10569         cancel_lru_locks osc
10570         # there may be some slab objects cached per core
10571         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10572         local before=$(num_objects)
10573         local count=$((512 * cpus))
10574         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10575         local margin=$((count / 10))
10576         if [[ -f $slab_lic/aliases ]]; then
10577                 local aliases=$(cat $slab_lic/aliases)
10578                 (( aliases > 0 )) && margin=$((margin * aliases))
10579         fi
10580
10581         echo "before slab objects: $before"
10582         for i in $(seq $count); do
10583                 touch $DIR/$tfile
10584                 rm -f $DIR/$tfile
10585         done
10586         cancel_lru_locks osc
10587         local after=$(num_objects)
10588         echo "created: $count, after slab objects: $after"
10589         # shared slab counts are not very accurate, allow significant margin
10590         # the main goal is that the cache growth is not permanently > $count
10591         while (( after > before + margin )); do
10592                 sleep 1
10593                 after=$(num_objects)
10594                 wait=$((wait + 1))
10595                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10596                 if (( wait > 60 )); then
10597                         error "inode slab grew from $before+$margin to $after"
10598                 fi
10599         done
10600 }
10601 run_test 76a "confirm clients recycle inodes properly ===="
10602
10603 test_76b() {
10604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10605         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10606
10607         local count=512
10608         local before=$(num_objects)
10609
10610         for i in $(seq $count); do
10611                 mkdir $DIR/$tdir
10612                 rmdir $DIR/$tdir
10613         done
10614
10615         local after=$(num_objects)
10616         local wait=0
10617
10618         while (( after > before )); do
10619                 sleep 1
10620                 after=$(num_objects)
10621                 wait=$((wait + 1))
10622                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10623                 if (( wait > 60 )); then
10624                         error "inode slab grew from $before to $after"
10625                 fi
10626         done
10627
10628         echo "slab objects before: $before, after: $after"
10629 }
10630 run_test 76b "confirm clients recycle directory inodes properly ===="
10631
10632 export ORIG_CSUM=""
10633 set_checksums()
10634 {
10635         # Note: in sptlrpc modes which enable its own bulk checksum, the
10636         # original crc32_le bulk checksum will be automatically disabled,
10637         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10638         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10639         # In this case set_checksums() will not be no-op, because sptlrpc
10640         # bulk checksum will be enabled all through the test.
10641
10642         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10643         lctl set_param -n osc.*.checksums $1
10644         return 0
10645 }
10646
10647 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10648                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10649 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10650                              tr -d [] | head -n1)}
10651 set_checksum_type()
10652 {
10653         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10654         rc=$?
10655         log "set checksum type to $1, rc = $rc"
10656         return $rc
10657 }
10658
10659 get_osc_checksum_type()
10660 {
10661         # arugment 1: OST name, like OST0000
10662         ost=$1
10663         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10664                         sed 's/.*\[\(.*\)\].*/\1/g')
10665         rc=$?
10666         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10667         echo $checksum_type
10668 }
10669
10670 F77_TMP=$TMP/f77-temp
10671 F77SZ=8
10672 setup_f77() {
10673         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10674                 error "error writing to $F77_TMP"
10675 }
10676
10677 test_77a() { # bug 10889
10678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10679         $GSS && skip_env "could not run with gss"
10680
10681         [ ! -f $F77_TMP ] && setup_f77
10682         set_checksums 1
10683         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10684         set_checksums 0
10685         rm -f $DIR/$tfile
10686 }
10687 run_test 77a "normal checksum read/write operation"
10688
10689 test_77b() { # bug 10889
10690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10691         $GSS && skip_env "could not run with gss"
10692
10693         [ ! -f $F77_TMP ] && setup_f77
10694         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10695         $LCTL set_param fail_loc=0x80000409
10696         set_checksums 1
10697
10698         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10699                 error "dd error: $?"
10700         $LCTL set_param fail_loc=0
10701
10702         for algo in $CKSUM_TYPES; do
10703                 cancel_lru_locks osc
10704                 set_checksum_type $algo
10705                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10706                 $LCTL set_param fail_loc=0x80000408
10707                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10708                 $LCTL set_param fail_loc=0
10709         done
10710         set_checksums 0
10711         set_checksum_type $ORIG_CSUM_TYPE
10712         rm -f $DIR/$tfile
10713 }
10714 run_test 77b "checksum error on client write, read"
10715
10716 cleanup_77c() {
10717         trap 0
10718         set_checksums 0
10719         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10720         $check_ost &&
10721                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10722         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10723         $check_ost && [ -n "$ost_file_prefix" ] &&
10724                 do_facet ost1 rm -f ${ost_file_prefix}\*
10725 }
10726
10727 test_77c() {
10728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10729         $GSS && skip_env "could not run with gss"
10730         remote_ost_nodsh && skip "remote OST with nodsh"
10731
10732         local bad1
10733         local osc_file_prefix
10734         local osc_file
10735         local check_ost=false
10736         local ost_file_prefix
10737         local ost_file
10738         local orig_cksum
10739         local dump_cksum
10740         local fid
10741
10742         # ensure corruption will occur on first OSS/OST
10743         $LFS setstripe -i 0 $DIR/$tfile
10744
10745         [ ! -f $F77_TMP ] && setup_f77
10746         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10747                 error "dd write error: $?"
10748         fid=$($LFS path2fid $DIR/$tfile)
10749
10750         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10751         then
10752                 check_ost=true
10753                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10754                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10755         else
10756                 echo "OSS do not support bulk pages dump upon error"
10757         fi
10758
10759         osc_file_prefix=$($LCTL get_param -n debug_path)
10760         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10761
10762         trap cleanup_77c EXIT
10763
10764         set_checksums 1
10765         # enable bulk pages dump upon error on Client
10766         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10767         # enable bulk pages dump upon error on OSS
10768         $check_ost &&
10769                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10770
10771         # flush Client cache to allow next read to reach OSS
10772         cancel_lru_locks osc
10773
10774         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10775         $LCTL set_param fail_loc=0x80000408
10776         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10777         $LCTL set_param fail_loc=0
10778
10779         rm -f $DIR/$tfile
10780
10781         # check cksum dump on Client
10782         osc_file=$(ls ${osc_file_prefix}*)
10783         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10784         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10785         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10786         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10787         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10788                      cksum)
10789         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10790         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10791                 error "dump content does not match on Client"
10792
10793         $check_ost || skip "No need to check cksum dump on OSS"
10794
10795         # check cksum dump on OSS
10796         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10797         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10798         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10799         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10800         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10801                 error "dump content does not match on OSS"
10802
10803         cleanup_77c
10804 }
10805 run_test 77c "checksum error on client read with debug"
10806
10807 test_77d() { # bug 10889
10808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10809         $GSS && skip_env "could not run with gss"
10810
10811         stack_trap "rm -f $DIR/$tfile"
10812         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10813         $LCTL set_param fail_loc=0x80000409
10814         set_checksums 1
10815         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10816                 error "direct write: rc=$?"
10817         $LCTL set_param fail_loc=0
10818         set_checksums 0
10819
10820         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10821         $LCTL set_param fail_loc=0x80000408
10822         set_checksums 1
10823         cancel_lru_locks osc
10824         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10825                 error "direct read: rc=$?"
10826         $LCTL set_param fail_loc=0
10827         set_checksums 0
10828 }
10829 run_test 77d "checksum error on OST direct write, read"
10830
10831 test_77f() { # bug 10889
10832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10833         $GSS && skip_env "could not run with gss"
10834
10835         set_checksums 1
10836         stack_trap "rm -f $DIR/$tfile"
10837         for algo in $CKSUM_TYPES; do
10838                 cancel_lru_locks osc
10839                 set_checksum_type $algo
10840                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10841                 $LCTL set_param fail_loc=0x409
10842                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10843                         error "direct write succeeded"
10844                 $LCTL set_param fail_loc=0
10845         done
10846         set_checksum_type $ORIG_CSUM_TYPE
10847         set_checksums 0
10848 }
10849 run_test 77f "repeat checksum error on write (expect error)"
10850
10851 test_77g() { # bug 10889
10852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10853         $GSS && skip_env "could not run with gss"
10854         remote_ost_nodsh && skip "remote OST with nodsh"
10855
10856         [ ! -f $F77_TMP ] && setup_f77
10857
10858         local file=$DIR/$tfile
10859         stack_trap "rm -f $file" EXIT
10860
10861         $LFS setstripe -c 1 -i 0 $file
10862         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10863         do_facet ost1 lctl set_param fail_loc=0x8000021a
10864         set_checksums 1
10865         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10866                 error "write error: rc=$?"
10867         do_facet ost1 lctl set_param fail_loc=0
10868         set_checksums 0
10869
10870         cancel_lru_locks osc
10871         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10872         do_facet ost1 lctl set_param fail_loc=0x8000021b
10873         set_checksums 1
10874         cmp $F77_TMP $file || error "file compare failed"
10875         do_facet ost1 lctl set_param fail_loc=0
10876         set_checksums 0
10877 }
10878 run_test 77g "checksum error on OST write, read"
10879
10880 test_77k() { # LU-10906
10881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10882         $GSS && skip_env "could not run with gss"
10883
10884         local cksum_param="osc.$FSNAME*.checksums"
10885         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10886         local checksum
10887         local i
10888
10889         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10890         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10891         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10892
10893         for i in 0 1; do
10894                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10895                         error "failed to set checksum=$i on MGS"
10896                 wait_update $HOSTNAME "$get_checksum" $i
10897                 #remount
10898                 echo "remount client, checksum should be $i"
10899                 remount_client $MOUNT || error "failed to remount client"
10900                 checksum=$(eval $get_checksum)
10901                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10902         done
10903         # remove persistent param to avoid races with checksum mountopt below
10904         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10905                 error "failed to delete checksum on MGS"
10906
10907         for opt in "checksum" "nochecksum"; do
10908                 #remount with mount option
10909                 echo "remount client with option $opt, checksum should be $i"
10910                 umount_client $MOUNT || error "failed to umount client"
10911                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10912                         error "failed to mount client with option '$opt'"
10913                 checksum=$(eval $get_checksum)
10914                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10915                 i=$((i - 1))
10916         done
10917
10918         remount_client $MOUNT || error "failed to remount client"
10919 }
10920 run_test 77k "enable/disable checksum correctly"
10921
10922 test_77l() {
10923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10924         $GSS && skip_env "could not run with gss"
10925
10926         set_checksums 1
10927         stack_trap "set_checksums $ORIG_CSUM" EXIT
10928         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10929
10930         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10931
10932         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10933         for algo in $CKSUM_TYPES; do
10934                 set_checksum_type $algo || error "fail to set checksum type $algo"
10935                 osc_algo=$(get_osc_checksum_type OST0000)
10936                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10937
10938                 # no locks, no reqs to let the connection idle
10939                 cancel_lru_locks osc
10940                 lru_resize_disable osc
10941                 wait_osc_import_state client ost1 IDLE
10942
10943                 # ensure ost1 is connected
10944                 stat $DIR/$tfile >/dev/null || error "can't stat"
10945                 wait_osc_import_state client ost1 FULL
10946
10947                 osc_algo=$(get_osc_checksum_type OST0000)
10948                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10949         done
10950         return 0
10951 }
10952 run_test 77l "preferred checksum type is remembered after reconnected"
10953
10954 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10955 rm -f $F77_TMP
10956 unset F77_TMP
10957
10958 test_77m() {
10959         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10960                 skip "Need at least version 2.14.52"
10961         local param=checksum_speed
10962
10963         $LCTL get_param $param || error "reading $param failed"
10964
10965         csum_speeds=$($LCTL get_param -n $param)
10966
10967         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10968                 error "known checksum types are missing"
10969 }
10970 run_test 77m "Verify checksum_speed is correctly read"
10971
10972 check_filefrag_77n() {
10973         local nr_ext=0
10974         local starts=()
10975         local ends=()
10976
10977         while read extidx a b start end rest; do
10978                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10979                         nr_ext=$(( $nr_ext + 1 ))
10980                         starts+=( ${start%..} )
10981                         ends+=( ${end%:} )
10982                 fi
10983         done < <( filefrag -sv $1 )
10984
10985         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10986         return 1
10987 }
10988
10989 test_77n() {
10990         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10991
10992         touch $DIR/$tfile
10993         $TRUNCATE $DIR/$tfile 0
10994         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10995         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10996         check_filefrag_77n $DIR/$tfile ||
10997                 skip "$tfile blocks not contiguous around hole"
10998
10999         set_checksums 1
11000         stack_trap "set_checksums $ORIG_CSUM" EXIT
11001         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11002         stack_trap "rm -f $DIR/$tfile"
11003
11004         for algo in $CKSUM_TYPES; do
11005                 if [[ "$algo" =~ ^t10 ]]; then
11006                         set_checksum_type $algo ||
11007                                 error "fail to set checksum type $algo"
11008                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11009                                 error "fail to read $tfile with $algo"
11010                 fi
11011         done
11012         rm -f $DIR/$tfile
11013         return 0
11014 }
11015 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11016
11017 test_77o() {
11018         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11019                 skip "Need MDS version at least 2.14.55"
11020         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11021                 skip "Need OST version at least 2.14.55"
11022         local ofd=obdfilter
11023         local mdt=mdt
11024
11025         # print OST checksum_type
11026         echo "$ofd.$FSNAME-*.checksum_type:"
11027         do_nodes $(comma_list $(osts_nodes)) \
11028                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11029
11030         # print MDT checksum_type
11031         echo "$mdt.$FSNAME-*.checksum_type:"
11032         do_nodes $(comma_list $(mdts_nodes)) \
11033                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11034
11035         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11036                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11037
11038         (( $o_count == $OSTCOUNT )) ||
11039                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11040
11041         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11042                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11043
11044         (( $m_count == $MDSCOUNT )) ||
11045                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11046 }
11047 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11048
11049 cleanup_test_78() {
11050         trap 0
11051         rm -f $DIR/$tfile
11052 }
11053
11054 test_78() { # bug 10901
11055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11056         remote_ost || skip_env "local OST"
11057
11058         NSEQ=5
11059         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11060         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11061         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11062         echo "MemTotal: $MEMTOTAL"
11063
11064         # reserve 256MB of memory for the kernel and other running processes,
11065         # and then take 1/2 of the remaining memory for the read/write buffers.
11066         if [ $MEMTOTAL -gt 512 ] ;then
11067                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11068         else
11069                 # for those poor memory-starved high-end clusters...
11070                 MEMTOTAL=$((MEMTOTAL / 2))
11071         fi
11072         echo "Mem to use for directio: $MEMTOTAL"
11073
11074         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11075         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11076         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11077         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11078                 head -n1)
11079         echo "Smallest OST: $SMALLESTOST"
11080         [[ $SMALLESTOST -lt 10240 ]] &&
11081                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11082
11083         trap cleanup_test_78 EXIT
11084
11085         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11086                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11087
11088         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11089         echo "File size: $F78SIZE"
11090         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11091         for i in $(seq 1 $NSEQ); do
11092                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11093                 echo directIO rdwr round $i of $NSEQ
11094                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11095         done
11096
11097         cleanup_test_78
11098 }
11099 run_test 78 "handle large O_DIRECT writes correctly ============"
11100
11101 test_79() { # bug 12743
11102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11103
11104         wait_delete_completed
11105
11106         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11107         BKFREE=$(calc_osc_kbytes kbytesfree)
11108         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11109
11110         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11111         DFTOTAL=`echo $STRING | cut -d, -f1`
11112         DFUSED=`echo $STRING  | cut -d, -f2`
11113         DFAVAIL=`echo $STRING | cut -d, -f3`
11114         DFFREE=$(($DFTOTAL - $DFUSED))
11115
11116         ALLOWANCE=$((64 * $OSTCOUNT))
11117
11118         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11119            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11120                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11121         fi
11122         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11123            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11124                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11125         fi
11126         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11127            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11128                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11129         fi
11130 }
11131 run_test 79 "df report consistency check ======================="
11132
11133 test_80() { # bug 10718
11134         remote_ost_nodsh && skip "remote OST with nodsh"
11135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11136
11137         # relax strong synchronous semantics for slow backends like ZFS
11138         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11139                 local soc="obdfilter.*.sync_lock_cancel"
11140                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11141
11142                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11143                 if [ -z "$save" ]; then
11144                         soc="obdfilter.*.sync_on_lock_cancel"
11145                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11146                 fi
11147
11148                 if [ "$save" != "never" ]; then
11149                         local hosts=$(comma_list $(osts_nodes))
11150
11151                         do_nodes $hosts $LCTL set_param $soc=never
11152                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11153                 fi
11154         fi
11155
11156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11157         sync; sleep 1; sync
11158         local before=$(date +%s)
11159         cancel_lru_locks osc
11160         local after=$(date +%s)
11161         local diff=$((after - before))
11162         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11163
11164         rm -f $DIR/$tfile
11165 }
11166 run_test 80 "Page eviction is equally fast at high offsets too"
11167
11168 test_81a() { # LU-456
11169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11170         remote_ost_nodsh && skip "remote OST with nodsh"
11171
11172         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11173         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11174         do_facet ost1 lctl set_param fail_loc=0x80000228
11175
11176         # write should trigger a retry and success
11177         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11178         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11179         RC=$?
11180         if [ $RC -ne 0 ] ; then
11181                 error "write should success, but failed for $RC"
11182         fi
11183 }
11184 run_test 81a "OST should retry write when get -ENOSPC ==============="
11185
11186 test_81b() { # LU-456
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188         remote_ost_nodsh && skip "remote OST with nodsh"
11189
11190         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11191         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11192         do_facet ost1 lctl set_param fail_loc=0x228
11193
11194         # write should retry several times and return -ENOSPC finally
11195         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11196         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11197         RC=$?
11198         ENOSPC=28
11199         if [ $RC -ne $ENOSPC ] ; then
11200                 error "dd should fail for -ENOSPC, but succeed."
11201         fi
11202 }
11203 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11204
11205 test_99() {
11206         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11207
11208         test_mkdir $DIR/$tdir.cvsroot
11209         chown $RUNAS_ID $DIR/$tdir.cvsroot
11210
11211         cd $TMP
11212         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11213
11214         cd /etc/init.d
11215         # some versions of cvs import exit(1) when asked to import links or
11216         # files they can't read.  ignore those files.
11217         local toignore=$(find . -type l -printf '-I %f\n' -o \
11218                          ! -perm /4 -printf '-I %f\n')
11219         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11220                 $tdir.reposname vtag rtag
11221
11222         cd $DIR
11223         test_mkdir $DIR/$tdir.reposname
11224         chown $RUNAS_ID $DIR/$tdir.reposname
11225         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11226
11227         cd $DIR/$tdir.reposname
11228         $RUNAS touch foo99
11229         $RUNAS cvs add -m 'addmsg' foo99
11230         $RUNAS cvs update
11231         $RUNAS cvs commit -m 'nomsg' foo99
11232         rm -fr $DIR/$tdir.cvsroot
11233 }
11234 run_test 99 "cvs strange file/directory operations"
11235
11236 test_100() {
11237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11238         [[ "$NETTYPE" =~ tcp ]] ||
11239                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11240         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11241         remote_ost_nodsh && skip "remote OST with nodsh"
11242         remote_mds_nodsh && skip "remote MDS with nodsh"
11243         remote_servers || skip "useless for local single node setup"
11244
11245         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11246                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11247
11248                 rc=0
11249                 if (( ${LOCAL/*:/} >= 1024 )); then
11250                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11251                         ss -tna
11252                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11253                 fi
11254         done
11255         (( $rc == 0 )) || error "privileged port not found" )
11256 }
11257 run_test 100 "check local port using privileged port"
11258
11259 function get_named_value()
11260 {
11261     local tag=$1
11262
11263     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11264 }
11265
11266 test_101a() {
11267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11268
11269         local s
11270         local discard
11271         local nreads=10000
11272         local cache_limit=32
11273
11274         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11275         $LCTL set_param -n llite.*.read_ahead_stats=0
11276         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11277                               awk '/^max_cached_mb/ { print $2 }')
11278         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11279         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11280
11281         #
11282         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11283         #
11284         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11285         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11286
11287         discard=0
11288         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11289                    get_named_value 'read.but.discarded'); do
11290                         discard=$(($discard + $s))
11291         done
11292
11293         $LCTL get_param osc.*-osc*.rpc_stats
11294         $LCTL get_param llite.*.read_ahead_stats
11295
11296         # Discard is generally zero, but sometimes a few random reads line up
11297         # and trigger larger readahead, which is wasted & leads to discards.
11298         if [[ $(($discard)) -gt $nreads ]]; then
11299                 error "too many ($discard) discarded pages"
11300         fi
11301         rm -f $DIR/$tfile || true
11302 }
11303 run_test 101a "check read-ahead for random reads"
11304
11305 setup_test101bc() {
11306         test_mkdir $DIR/$tdir
11307         local ssize=$1
11308         local FILE_LENGTH=$2
11309         STRIPE_OFFSET=0
11310
11311         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11312
11313         local list=$(comma_list $(osts_nodes))
11314         set_osd_param $list '' read_cache_enable 0
11315         set_osd_param $list '' writethrough_cache_enable 0
11316
11317         trap cleanup_test101bc EXIT
11318         # prepare the read-ahead file
11319         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11320
11321         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11322                                 count=$FILE_SIZE_MB 2> /dev/null
11323
11324 }
11325
11326 cleanup_test101bc() {
11327         trap 0
11328         rm -rf $DIR/$tdir
11329         rm -f $DIR/$tfile
11330
11331         local list=$(comma_list $(osts_nodes))
11332         set_osd_param $list '' read_cache_enable 1
11333         set_osd_param $list '' writethrough_cache_enable 1
11334 }
11335
11336 ra_check_101() {
11337         local read_size=$1
11338         local stripe_size=$2
11339         local stride_length=$((stripe_size / read_size))
11340         local stride_width=$((stride_length * OSTCOUNT))
11341         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11342                                 (stride_width - stride_length) ))
11343         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11344                   get_named_value 'read.but.discarded' | calc_sum)
11345
11346         if [[ $discard -gt $discard_limit ]]; then
11347                 $LCTL get_param llite.*.read_ahead_stats
11348                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11349         else
11350                 echo "Read-ahead success for size ${read_size}"
11351         fi
11352 }
11353
11354 test_101b() {
11355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11356         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11357
11358         local STRIPE_SIZE=1048576
11359         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11360
11361         if [ $SLOW == "yes" ]; then
11362                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11363         else
11364                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11365         fi
11366
11367         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11368
11369         # prepare the read-ahead file
11370         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11371         cancel_lru_locks osc
11372         for BIDX in 2 4 8 16 32 64 128 256
11373         do
11374                 local BSIZE=$((BIDX*4096))
11375                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11376                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11377                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11378                 $LCTL set_param -n llite.*.read_ahead_stats=0
11379                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11380                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11381                 cancel_lru_locks osc
11382                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11383         done
11384         cleanup_test101bc
11385         true
11386 }
11387 run_test 101b "check stride-io mode read-ahead ================="
11388
11389 test_101c() {
11390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11391
11392         local STRIPE_SIZE=1048576
11393         local FILE_LENGTH=$((STRIPE_SIZE*100))
11394         local nreads=10000
11395         local rsize=65536
11396         local osc_rpc_stats
11397
11398         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11399
11400         cancel_lru_locks osc
11401         $LCTL set_param osc.*.rpc_stats=0
11402         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11403         $LCTL get_param osc.*.rpc_stats
11404         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11405                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11406                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11407                 local size
11408
11409                 if [ $lines -le 20 ]; then
11410                         echo "continue debug"
11411                         continue
11412                 fi
11413                 for size in 1 2 4 8; do
11414                         local rpc=$(echo "$stats" |
11415                                     awk '($1 == "'$size':") {print $2; exit; }')
11416                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11417                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11418                 done
11419                 echo "$osc_rpc_stats check passed!"
11420         done
11421         cleanup_test101bc
11422         true
11423 }
11424 run_test 101c "check stripe_size aligned read-ahead"
11425
11426 test_101d() {
11427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11428
11429         local file=$DIR/$tfile
11430         local sz_MB=${FILESIZE_101d:-80}
11431         local ra_MB=${READAHEAD_MB:-40}
11432
11433         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11434         [ $free_MB -lt $sz_MB ] &&
11435                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11436
11437         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11438         $LFS setstripe -c -1 $file || error "setstripe failed"
11439
11440         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11441         echo Cancel LRU locks on lustre client to flush the client cache
11442         cancel_lru_locks osc
11443
11444         echo Disable read-ahead
11445         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11446         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11447         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11448         $LCTL get_param -n llite.*.max_read_ahead_mb
11449
11450         echo "Reading the test file $file with read-ahead disabled"
11451         local sz_KB=$((sz_MB * 1024 / 4))
11452         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11453         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11454         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11455                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11456
11457         echo "Cancel LRU locks on lustre client to flush the client cache"
11458         cancel_lru_locks osc
11459         echo Enable read-ahead with ${ra_MB}MB
11460         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11461
11462         echo "Reading the test file $file with read-ahead enabled"
11463         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11464                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11465
11466         echo "read-ahead disabled time read $raOFF"
11467         echo "read-ahead enabled time read $raON"
11468
11469         rm -f $file
11470         wait_delete_completed
11471
11472         # use awk for this check instead of bash because it handles decimals
11473         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11474                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11475 }
11476 run_test 101d "file read with and without read-ahead enabled"
11477
11478 test_101e() {
11479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11480
11481         local file=$DIR/$tfile
11482         local size_KB=500  #KB
11483         local count=100
11484         local bsize=1024
11485
11486         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11487         local need_KB=$((count * size_KB))
11488         [[ $free_KB -le $need_KB ]] &&
11489                 skip_env "Need free space $need_KB, have $free_KB"
11490
11491         echo "Creating $count ${size_KB}K test files"
11492         for ((i = 0; i < $count; i++)); do
11493                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11494         done
11495
11496         echo "Cancel LRU locks on lustre client to flush the client cache"
11497         cancel_lru_locks $OSC
11498
11499         echo "Reset readahead stats"
11500         $LCTL set_param -n llite.*.read_ahead_stats=0
11501
11502         for ((i = 0; i < $count; i++)); do
11503                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11504         done
11505
11506         $LCTL get_param llite.*.max_cached_mb
11507         $LCTL get_param llite.*.read_ahead_stats
11508         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11509                      get_named_value 'misses' | calc_sum)
11510
11511         for ((i = 0; i < $count; i++)); do
11512                 rm -rf $file.$i 2>/dev/null
11513         done
11514
11515         #10000 means 20% reads are missing in readahead
11516         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11517 }
11518 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11519
11520 test_101f() {
11521         which iozone || skip_env "no iozone installed"
11522
11523         local old_debug=$($LCTL get_param debug)
11524         old_debug=${old_debug#*=}
11525         $LCTL set_param debug="reada mmap"
11526
11527         # create a test file
11528         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11529
11530         echo Cancel LRU locks on lustre client to flush the client cache
11531         cancel_lru_locks osc
11532
11533         echo Reset readahead stats
11534         $LCTL set_param -n llite.*.read_ahead_stats=0
11535
11536         echo mmap read the file with small block size
11537         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11538                 > /dev/null 2>&1
11539
11540         echo checking missing pages
11541         $LCTL get_param llite.*.read_ahead_stats
11542         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11543                         get_named_value 'misses' | calc_sum)
11544
11545         $LCTL set_param debug="$old_debug"
11546         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11547         rm -f $DIR/$tfile
11548 }
11549 run_test 101f "check mmap read performance"
11550
11551 test_101g_brw_size_test() {
11552         local mb=$1
11553         local pages=$((mb * 1048576 / PAGE_SIZE))
11554         local file=$DIR/$tfile
11555
11556         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11557                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11558         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11559                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11560                         return 2
11561         done
11562
11563         stack_trap "rm -f $file" EXIT
11564         $LCTL set_param -n osc.*.rpc_stats=0
11565
11566         # 10 RPCs should be enough for the test
11567         local count=10
11568         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11569                 { error "dd write ${mb} MB blocks failed"; return 3; }
11570         cancel_lru_locks osc
11571         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11572                 { error "dd write ${mb} MB blocks failed"; return 4; }
11573
11574         # calculate number of full-sized read and write RPCs
11575         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11576                 sed -n '/pages per rpc/,/^$/p' |
11577                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11578                 END { print reads,writes }'))
11579         # allow one extra full-sized read RPC for async readahead
11580         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11581                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11582         [[ ${rpcs[1]} == $count ]] ||
11583                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11584 }
11585
11586 test_101g() {
11587         remote_ost_nodsh && skip "remote OST with nodsh"
11588
11589         local rpcs
11590         local osts=$(get_facets OST)
11591         local list=$(comma_list $(osts_nodes))
11592         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11593         local brw_size="obdfilter.*.brw_size"
11594
11595         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11596
11597         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11598
11599         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11600                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11601                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11602            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11603                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11604                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11605
11606                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11607                         suffix="M"
11608
11609                 if [[ $orig_mb -lt 16 ]]; then
11610                         save_lustre_params $osts "$brw_size" > $p
11611                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11612                                 error "set 16MB RPC size failed"
11613
11614                         echo "remount client to enable new RPC size"
11615                         remount_client $MOUNT || error "remount_client failed"
11616                 fi
11617
11618                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11619                 # should be able to set brw_size=12, but no rpc_stats for that
11620                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11621         fi
11622
11623         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11624
11625         if [[ $orig_mb -lt 16 ]]; then
11626                 restore_lustre_params < $p
11627                 remount_client $MOUNT || error "remount_client restore failed"
11628         fi
11629
11630         rm -f $p $DIR/$tfile
11631 }
11632 run_test 101g "Big bulk(4/16 MiB) readahead"
11633
11634 test_101h() {
11635         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11636
11637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11638                 error "dd 70M file failed"
11639         echo Cancel LRU locks on lustre client to flush the client cache
11640         cancel_lru_locks osc
11641
11642         echo "Reset readahead stats"
11643         $LCTL set_param -n llite.*.read_ahead_stats 0
11644
11645         echo "Read 10M of data but cross 64M bundary"
11646         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11647         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11648                      get_named_value 'misses' | calc_sum)
11649         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11650         rm -f $p $DIR/$tfile
11651 }
11652 run_test 101h "Readahead should cover current read window"
11653
11654 test_101i() {
11655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11656                 error "dd 10M file failed"
11657
11658         local max_per_file_mb=$($LCTL get_param -n \
11659                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11660         cancel_lru_locks osc
11661         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11662         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11663                 error "set max_read_ahead_per_file_mb to 1 failed"
11664
11665         echo "Reset readahead stats"
11666         $LCTL set_param llite.*.read_ahead_stats=0
11667
11668         dd if=$DIR/$tfile of=/dev/null bs=2M
11669
11670         $LCTL get_param llite.*.read_ahead_stats
11671         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11672                      awk '/misses/ { print $2 }')
11673         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11674         rm -f $DIR/$tfile
11675 }
11676 run_test 101i "allow current readahead to exceed reservation"
11677
11678 test_101j() {
11679         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11680                 error "setstripe $DIR/$tfile failed"
11681         local file_size=$((1048576 * 16))
11682         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11683         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11684
11685         echo Disable read-ahead
11686         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11687
11688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11689         for blk in $PAGE_SIZE 1048576 $file_size; do
11690                 cancel_lru_locks osc
11691                 echo "Reset readahead stats"
11692                 $LCTL set_param -n llite.*.read_ahead_stats=0
11693                 local count=$(($file_size / $blk))
11694                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11695                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11696                              get_named_value 'failed.to.fast.read' | calc_sum)
11697                 $LCTL get_param -n llite.*.read_ahead_stats
11698                 [ $miss -eq $count ] || error "expected $count got $miss"
11699         done
11700
11701         rm -f $p $DIR/$tfile
11702 }
11703 run_test 101j "A complete read block should be submitted when no RA"
11704
11705 test_readahead_base() {
11706         local file=$DIR/$tfile
11707         local size=$1
11708         local iosz
11709         local ramax
11710         local ranum
11711
11712         $LCTL set_param -n llite.*.read_ahead_stats=0
11713         # The first page is not accounted into readahead
11714         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11715         iosz=$(((size + 1048575) / 1048576 * 1048576))
11716         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11717
11718         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11719         fallocate -l $size $file || error "failed to fallocate $file"
11720         cancel_lru_locks osc
11721         $MULTIOP $file or${iosz}c || error "failed to read $file"
11722         $LCTL get_param -n llite.*.read_ahead_stats
11723         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11724                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11725         (( $ranum <= $ramax )) ||
11726                 error "read-ahead pages is $ranum more than $ramax"
11727         rm -rf $file || error "failed to remove $file"
11728 }
11729
11730 test_101m()
11731 {
11732         local file=$DIR/$tfile
11733         local ramax
11734         local ranum
11735         local size
11736         local iosz
11737
11738         check_set_fallocate_or_skip
11739         stack_trap "rm -f $file" EXIT
11740
11741         test_readahead_base 4096
11742
11743         # file size: 16K = 16384
11744         test_readahead_base 16384
11745         test_readahead_base 16385
11746         test_readahead_base 16383
11747
11748         # file size: 1M + 1 = 1048576 + 1
11749         test_readahead_base 1048577
11750         # file size: 1M + 16K
11751         test_readahead_base $((1048576 + 16384))
11752
11753         # file size: stripe_size * (stripe_count - 1) + 16K
11754         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11755         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11756         # file size: stripe_size * stripe_count + 16K
11757         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11758         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11759         # file size: 2 * stripe_size * stripe_count + 16K
11760         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11761         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11762 }
11763 run_test 101m "read ahead for small file and last stripe of the file"
11764
11765 setup_test102() {
11766         test_mkdir $DIR/$tdir
11767         chown $RUNAS_ID $DIR/$tdir
11768         STRIPE_SIZE=65536
11769         STRIPE_OFFSET=1
11770         STRIPE_COUNT=$OSTCOUNT
11771         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11772
11773         trap cleanup_test102 EXIT
11774         cd $DIR
11775         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11776         cd $DIR/$tdir
11777         for num in 1 2 3 4; do
11778                 for count in $(seq 1 $STRIPE_COUNT); do
11779                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11780                                 local size=`expr $STRIPE_SIZE \* $num`
11781                                 local file=file"$num-$idx-$count"
11782                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11783                         done
11784                 done
11785         done
11786
11787         cd $DIR
11788         $1 tar cf $TMP/f102.tar $tdir --xattrs
11789 }
11790
11791 cleanup_test102() {
11792         trap 0
11793         rm -f $TMP/f102.tar
11794         rm -rf $DIR/d0.sanity/d102
11795 }
11796
11797 test_102a() {
11798         [ "$UID" != 0 ] && skip "must run as root"
11799         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11800                 skip_env "must have user_xattr"
11801
11802         [ -z "$(which setfattr 2>/dev/null)" ] &&
11803                 skip_env "could not find setfattr"
11804
11805         local testfile=$DIR/$tfile
11806
11807         touch $testfile
11808         echo "set/get xattr..."
11809         setfattr -n trusted.name1 -v value1 $testfile ||
11810                 error "setfattr -n trusted.name1=value1 $testfile failed"
11811         getfattr -n trusted.name1 $testfile 2> /dev/null |
11812           grep "trusted.name1=.value1" ||
11813                 error "$testfile missing trusted.name1=value1"
11814
11815         setfattr -n user.author1 -v author1 $testfile ||
11816                 error "setfattr -n user.author1=author1 $testfile failed"
11817         getfattr -n user.author1 $testfile 2> /dev/null |
11818           grep "user.author1=.author1" ||
11819                 error "$testfile missing trusted.author1=author1"
11820
11821         echo "listxattr..."
11822         setfattr -n trusted.name2 -v value2 $testfile ||
11823                 error "$testfile unable to set trusted.name2"
11824         setfattr -n trusted.name3 -v value3 $testfile ||
11825                 error "$testfile unable to set trusted.name3"
11826         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11827             grep "trusted.name" | wc -l) -eq 3 ] ||
11828                 error "$testfile missing 3 trusted.name xattrs"
11829
11830         setfattr -n user.author2 -v author2 $testfile ||
11831                 error "$testfile unable to set user.author2"
11832         setfattr -n user.author3 -v author3 $testfile ||
11833                 error "$testfile unable to set user.author3"
11834         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11835             grep "user.author" | wc -l) -eq 3 ] ||
11836                 error "$testfile missing 3 user.author xattrs"
11837
11838         echo "remove xattr..."
11839         setfattr -x trusted.name1 $testfile ||
11840                 error "$testfile error deleting trusted.name1"
11841         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11842                 error "$testfile did not delete trusted.name1 xattr"
11843
11844         setfattr -x user.author1 $testfile ||
11845                 error "$testfile error deleting user.author1"
11846         echo "set lustre special xattr ..."
11847         $LFS setstripe -c1 $testfile
11848         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11849                 awk -F "=" '/trusted.lov/ { print $2 }' )
11850         setfattr -n "trusted.lov" -v $lovea $testfile ||
11851                 error "$testfile doesn't ignore setting trusted.lov again"
11852         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11853                 error "$testfile allow setting invalid trusted.lov"
11854         rm -f $testfile
11855 }
11856 run_test 102a "user xattr test =================================="
11857
11858 check_102b_layout() {
11859         local layout="$*"
11860         local testfile=$DIR/$tfile
11861
11862         echo "test layout '$layout'"
11863         $LFS setstripe $layout $testfile || error "setstripe failed"
11864         $LFS getstripe -y $testfile
11865
11866         echo "get/set/list trusted.lov xattr ..." # b=10930
11867         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11868         [[ "$value" =~ "trusted.lov" ]] ||
11869                 error "can't get trusted.lov from $testfile"
11870         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11871                 error "getstripe failed"
11872
11873         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11874
11875         value=$(cut -d= -f2 <<<$value)
11876         # LU-13168: truncated xattr should fail if short lov_user_md header
11877         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11878                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11879         for len in $lens; do
11880                 echo "setfattr $len $testfile.2"
11881                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11882                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11883         done
11884         local stripe_size=$($LFS getstripe -S $testfile.2)
11885         local stripe_count=$($LFS getstripe -c $testfile.2)
11886         [[ $stripe_size -eq 65536 ]] ||
11887                 error "stripe size $stripe_size != 65536"
11888         [[ $stripe_count -eq $stripe_count_orig ]] ||
11889                 error "stripe count $stripe_count != $stripe_count_orig"
11890         rm $testfile $testfile.2
11891 }
11892
11893 test_102b() {
11894         [ -z "$(which setfattr 2>/dev/null)" ] &&
11895                 skip_env "could not find setfattr"
11896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11897
11898         # check plain layout
11899         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11900
11901         # and also check composite layout
11902         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11903
11904 }
11905 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11906
11907 test_102c() {
11908         [ -z "$(which setfattr 2>/dev/null)" ] &&
11909                 skip_env "could not find setfattr"
11910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11911
11912         # b10930: get/set/list lustre.lov xattr
11913         echo "get/set/list lustre.lov xattr ..."
11914         test_mkdir $DIR/$tdir
11915         chown $RUNAS_ID $DIR/$tdir
11916         local testfile=$DIR/$tdir/$tfile
11917         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11918                 error "setstripe failed"
11919         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11920                 error "getstripe failed"
11921         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11922         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11923
11924         local testfile2=${testfile}2
11925         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11926                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11927
11928         $RUNAS $MCREATE $testfile2
11929         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11930         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11931         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11932         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11933         [ $stripe_count -eq $STRIPECOUNT ] ||
11934                 error "stripe count $stripe_count != $STRIPECOUNT"
11935 }
11936 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11937
11938 compare_stripe_info1() {
11939         local stripe_index_all_zero=true
11940
11941         for num in 1 2 3 4; do
11942                 for count in $(seq 1 $STRIPE_COUNT); do
11943                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11944                                 local size=$((STRIPE_SIZE * num))
11945                                 local file=file"$num-$offset-$count"
11946                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11947                                 [[ $stripe_size -ne $size ]] &&
11948                                     error "$file: size $stripe_size != $size"
11949                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11950                                 # allow fewer stripes to be created, ORI-601
11951                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11952                                     error "$file: count $stripe_count != $count"
11953                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11954                                 [[ $stripe_index -ne 0 ]] &&
11955                                         stripe_index_all_zero=false
11956                         done
11957                 done
11958         done
11959         $stripe_index_all_zero &&
11960                 error "all files are being extracted starting from OST index 0"
11961         return 0
11962 }
11963
11964 have_xattrs_include() {
11965         tar --help | grep -q xattrs-include &&
11966                 echo --xattrs-include="lustre.*"
11967 }
11968
11969 test_102d() {
11970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11972
11973         XINC=$(have_xattrs_include)
11974         setup_test102
11975         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11976         cd $DIR/$tdir/$tdir
11977         compare_stripe_info1
11978 }
11979 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11980
11981 test_102f() {
11982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11984
11985         XINC=$(have_xattrs_include)
11986         setup_test102
11987         test_mkdir $DIR/$tdir.restore
11988         cd $DIR
11989         tar cf - --xattrs $tdir | tar xf - \
11990                 -C $DIR/$tdir.restore --xattrs $XINC
11991         cd $DIR/$tdir.restore/$tdir
11992         compare_stripe_info1
11993 }
11994 run_test 102f "tar copy files, not keep osts"
11995
11996 grow_xattr() {
11997         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11998                 skip "must have user_xattr"
11999         [ -z "$(which setfattr 2>/dev/null)" ] &&
12000                 skip_env "could not find setfattr"
12001         [ -z "$(which getfattr 2>/dev/null)" ] &&
12002                 skip_env "could not find getfattr"
12003
12004         local xsize=${1:-1024}  # in bytes
12005         local file=$DIR/$tfile
12006         local value="$(generate_string $xsize)"
12007         local xbig=trusted.big
12008         local toobig=$2
12009
12010         touch $file
12011         log "save $xbig on $file"
12012         if [ -z "$toobig" ]
12013         then
12014                 setfattr -n $xbig -v $value $file ||
12015                         error "saving $xbig on $file failed"
12016         else
12017                 setfattr -n $xbig -v $value $file &&
12018                         error "saving $xbig on $file succeeded"
12019                 return 0
12020         fi
12021
12022         local orig=$(get_xattr_value $xbig $file)
12023         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12024
12025         local xsml=trusted.sml
12026         log "save $xsml on $file"
12027         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12028
12029         local new=$(get_xattr_value $xbig $file)
12030         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12031
12032         log "grow $xsml on $file"
12033         setfattr -n $xsml -v "$value" $file ||
12034                 error "growing $xsml on $file failed"
12035
12036         new=$(get_xattr_value $xbig $file)
12037         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12038         log "$xbig still valid after growing $xsml"
12039
12040         rm -f $file
12041 }
12042
12043 test_102h() { # bug 15777
12044         grow_xattr 1024
12045 }
12046 run_test 102h "grow xattr from inside inode to external block"
12047
12048 test_102ha() {
12049         large_xattr_enabled || skip_env "ea_inode feature disabled"
12050
12051         echo "setting xattr of max xattr size: $(max_xattr_size)"
12052         grow_xattr $(max_xattr_size)
12053
12054         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12055         echo "This should fail:"
12056         grow_xattr $(($(max_xattr_size) + 10)) 1
12057 }
12058 run_test 102ha "grow xattr from inside inode to external inode"
12059
12060 test_102i() { # bug 17038
12061         [ -z "$(which getfattr 2>/dev/null)" ] &&
12062                 skip "could not find getfattr"
12063
12064         touch $DIR/$tfile
12065         ln -s $DIR/$tfile $DIR/${tfile}link
12066         getfattr -n trusted.lov $DIR/$tfile ||
12067                 error "lgetxattr on $DIR/$tfile failed"
12068         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12069                 grep -i "no such attr" ||
12070                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12071         rm -f $DIR/$tfile $DIR/${tfile}link
12072 }
12073 run_test 102i "lgetxattr test on symbolic link ============"
12074
12075 test_102j() {
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12078
12079         XINC=$(have_xattrs_include)
12080         setup_test102 "$RUNAS"
12081         chown $RUNAS_ID $DIR/$tdir
12082         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12083         cd $DIR/$tdir/$tdir
12084         compare_stripe_info1 "$RUNAS"
12085 }
12086 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12087
12088 test_102k() {
12089         [ -z "$(which setfattr 2>/dev/null)" ] &&
12090                 skip "could not find setfattr"
12091
12092         touch $DIR/$tfile
12093         # b22187 just check that does not crash for regular file.
12094         setfattr -n trusted.lov $DIR/$tfile
12095         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12096         local test_kdir=$DIR/$tdir
12097         test_mkdir $test_kdir
12098         local default_size=$($LFS getstripe -S $test_kdir)
12099         local default_count=$($LFS getstripe -c $test_kdir)
12100         local default_offset=$($LFS getstripe -i $test_kdir)
12101         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12102                 error 'dir setstripe failed'
12103         setfattr -n trusted.lov $test_kdir
12104         local stripe_size=$($LFS getstripe -S $test_kdir)
12105         local stripe_count=$($LFS getstripe -c $test_kdir)
12106         local stripe_offset=$($LFS getstripe -i $test_kdir)
12107         [ $stripe_size -eq $default_size ] ||
12108                 error "stripe size $stripe_size != $default_size"
12109         [ $stripe_count -eq $default_count ] ||
12110                 error "stripe count $stripe_count != $default_count"
12111         [ $stripe_offset -eq $default_offset ] ||
12112                 error "stripe offset $stripe_offset != $default_offset"
12113         rm -rf $DIR/$tfile $test_kdir
12114 }
12115 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12116
12117 test_102l() {
12118         [ -z "$(which getfattr 2>/dev/null)" ] &&
12119                 skip "could not find getfattr"
12120
12121         # LU-532 trusted. xattr is invisible to non-root
12122         local testfile=$DIR/$tfile
12123
12124         touch $testfile
12125
12126         echo "listxattr as user..."
12127         chown $RUNAS_ID $testfile
12128         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12129             grep -q "trusted" &&
12130                 error "$testfile trusted xattrs are user visible"
12131
12132         return 0;
12133 }
12134 run_test 102l "listxattr size test =================================="
12135
12136 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12137         local path=$DIR/$tfile
12138         touch $path
12139
12140         listxattr_size_check $path || error "listattr_size_check $path failed"
12141 }
12142 run_test 102m "Ensure listxattr fails on small bufffer ========"
12143
12144 cleanup_test102
12145
12146 getxattr() { # getxattr path name
12147         # Return the base64 encoding of the value of xattr name on path.
12148         local path=$1
12149         local name=$2
12150
12151         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12152         # file: $path
12153         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12154         #
12155         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12156
12157         getfattr --absolute-names --encoding=base64 --name=$name $path |
12158                 awk -F= -v name=$name '$1 == name {
12159                         print substr($0, index($0, "=") + 1);
12160         }'
12161 }
12162
12163 test_102n() { # LU-4101 mdt: protect internal xattrs
12164         [ -z "$(which setfattr 2>/dev/null)" ] &&
12165                 skip "could not find setfattr"
12166         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12167         then
12168                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12169         fi
12170
12171         local file0=$DIR/$tfile.0
12172         local file1=$DIR/$tfile.1
12173         local xattr0=$TMP/$tfile.0
12174         local xattr1=$TMP/$tfile.1
12175         local namelist="lov lma lmv link fid version som hsm"
12176         local name
12177         local value
12178
12179         rm -rf $file0 $file1 $xattr0 $xattr1
12180         touch $file0 $file1
12181
12182         # Get 'before' xattrs of $file1.
12183         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12184
12185         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12186                 namelist+=" lfsck_namespace"
12187         for name in $namelist; do
12188                 # Try to copy xattr from $file0 to $file1.
12189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12190
12191                 setfattr --name=trusted.$name --value="$value" $file1 ||
12192                         error "setxattr 'trusted.$name' failed"
12193
12194                 # Try to set a garbage xattr.
12195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12196
12197                 if [[ x$name == "xlov" ]]; then
12198                         setfattr --name=trusted.lov --value="$value" $file1 &&
12199                         error "setxattr invalid 'trusted.lov' success"
12200                 else
12201                         setfattr --name=trusted.$name --value="$value" $file1 ||
12202                                 error "setxattr invalid 'trusted.$name' failed"
12203                 fi
12204
12205                 # Try to remove the xattr from $file1. We don't care if this
12206                 # appears to succeed or fail, we just don't want there to be
12207                 # any changes or crashes.
12208                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12209         done
12210
12211         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12212         then
12213                 name="lfsck_ns"
12214                 # Try to copy xattr from $file0 to $file1.
12215                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12216
12217                 setfattr --name=trusted.$name --value="$value" $file1 ||
12218                         error "setxattr 'trusted.$name' failed"
12219
12220                 # Try to set a garbage xattr.
12221                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12222
12223                 setfattr --name=trusted.$name --value="$value" $file1 ||
12224                         error "setxattr 'trusted.$name' failed"
12225
12226                 # Try to remove the xattr from $file1. We don't care if this
12227                 # appears to succeed or fail, we just don't want there to be
12228                 # any changes or crashes.
12229                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12230         fi
12231
12232         # Get 'after' xattrs of file1.
12233         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12234
12235         if ! diff $xattr0 $xattr1; then
12236                 error "before and after xattrs of '$file1' differ"
12237         fi
12238
12239         rm -rf $file0 $file1 $xattr0 $xattr1
12240
12241         return 0
12242 }
12243 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12244
12245 test_102p() { # LU-4703 setxattr did not check ownership
12246         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12247                 skip "MDS needs to be at least 2.5.56"
12248
12249         local testfile=$DIR/$tfile
12250
12251         touch $testfile
12252
12253         echo "setfacl as user..."
12254         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12255         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12256
12257         echo "setfattr as user..."
12258         setfacl -m "u:$RUNAS_ID:---" $testfile
12259         $RUNAS setfattr -x system.posix_acl_access $testfile
12260         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12261 }
12262 run_test 102p "check setxattr(2) correctly fails without permission"
12263
12264 test_102q() {
12265         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12266                 skip "MDS needs to be at least 2.6.92"
12267
12268         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12269 }
12270 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12271
12272 test_102r() {
12273         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12274                 skip "MDS needs to be at least 2.6.93"
12275
12276         touch $DIR/$tfile || error "touch"
12277         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12278         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12279         rm $DIR/$tfile || error "rm"
12280
12281         #normal directory
12282         mkdir -p $DIR/$tdir || error "mkdir"
12283         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12284         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12285         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12286                 error "$testfile error deleting user.author1"
12287         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12288                 grep "user.$(basename $tdir)" &&
12289                 error "$tdir did not delete user.$(basename $tdir)"
12290         rmdir $DIR/$tdir || error "rmdir"
12291
12292         #striped directory
12293         test_mkdir $DIR/$tdir
12294         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12295         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12296         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12297                 error "$testfile error deleting user.author1"
12298         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12299                 grep "user.$(basename $tdir)" &&
12300                 error "$tdir did not delete user.$(basename $tdir)"
12301         rmdir $DIR/$tdir || error "rm striped dir"
12302 }
12303 run_test 102r "set EAs with empty values"
12304
12305 test_102s() {
12306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12307                 skip "MDS needs to be at least 2.11.52"
12308
12309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12310
12311         save_lustre_params client "llite.*.xattr_cache" > $save
12312
12313         for cache in 0 1; do
12314                 lctl set_param llite.*.xattr_cache=$cache
12315
12316                 rm -f $DIR/$tfile
12317                 touch $DIR/$tfile || error "touch"
12318                 for prefix in lustre security system trusted user; do
12319                         # Note getxattr() may fail with 'Operation not
12320                         # supported' or 'No such attribute' depending
12321                         # on prefix and cache.
12322                         getfattr -n $prefix.n102s $DIR/$tfile &&
12323                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12324                 done
12325         done
12326
12327         restore_lustre_params < $save
12328 }
12329 run_test 102s "getting nonexistent xattrs should fail"
12330
12331 test_102t() {
12332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12333                 skip "MDS needs to be at least 2.11.52"
12334
12335         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12336
12337         save_lustre_params client "llite.*.xattr_cache" > $save
12338
12339         for cache in 0 1; do
12340                 lctl set_param llite.*.xattr_cache=$cache
12341
12342                 for buf_size in 0 256; do
12343                         rm -f $DIR/$tfile
12344                         touch $DIR/$tfile || error "touch"
12345                         setfattr -n user.multiop $DIR/$tfile
12346                         $MULTIOP $DIR/$tfile oa$buf_size ||
12347                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12348                 done
12349         done
12350
12351         restore_lustre_params < $save
12352 }
12353 run_test 102t "zero length xattr values handled correctly"
12354
12355 run_acl_subtest()
12356 {
12357         local test=$LUSTRE/tests/acl/$1.test
12358         local tmp=$(mktemp -t $1-XXXXXX).test
12359         local bin=$2
12360         local dmn=$3
12361         local grp=$4
12362         local nbd=$5
12363         export LANG=C
12364
12365
12366         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12367         local sedgroups="-e s/:users/:$grp/g"
12368         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12369
12370         sed $sedusers $sedgroups < $test > $tmp
12371         stack_trap "rm -f $tmp"
12372         [[ -s $tmp ]] || error "sed failed to create test script"
12373
12374         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12375         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12376 }
12377
12378 test_103a() {
12379         [ "$UID" != 0 ] && skip "must run as root"
12380         $GSS && skip_env "could not run under gss"
12381         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12382                 skip_env "must have acl enabled"
12383         which setfacl || skip_env "could not find setfacl"
12384         remote_mds_nodsh && skip "remote MDS with nodsh"
12385
12386         local mdts=$(comma_list $(mdts_nodes))
12387         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12388
12389         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12390         stack_trap "[[ -z \"$saved\" ]] || \
12391                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12392
12393         ACLBIN=${ACLBIN:-"bin"}
12394         ACLDMN=${ACLDMN:-"daemon"}
12395         ACLGRP=${ACLGRP:-"users"}
12396         ACLNBD=${ACLNBD:-"nobody"}
12397
12398         if ! id $ACLBIN ||
12399            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12400                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12401                 ACLBIN=$USER0
12402                 if ! id $ACLBIN ; then
12403                         cat /etc/passwd
12404                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12405                 fi
12406         fi
12407         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12408            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12409                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12410                 ACLDMN=$USER1
12411                 if ! id $ACLDMN ; then
12412                         cat /etc/passwd
12413                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12414                 fi
12415         fi
12416         if ! getent group $ACLGRP; then
12417                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12418                 ACLGRP="$TSTUSR"
12419                 if ! getent group $ACLGRP; then
12420                         echo "cannot find group '$ACLGRP', adding it"
12421                         cat /etc/group
12422                         add_group 60000 $ACLGRP
12423                 fi
12424         fi
12425
12426         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12427         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12428         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12429
12430         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12431                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12432                 ACLGRP="$TSTUSR"
12433                 if ! getent group $ACLGRP; then
12434                         echo "cannot find group '$ACLGRP', adding it"
12435                         cat /etc/group
12436                         add_group 60000 $ACLGRP
12437                 fi
12438                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12439                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12440                         cat /etc/group
12441                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12442                 fi
12443         fi
12444
12445         gpasswd -a $ACLDMN $ACLBIN ||
12446                 error "setting client group failed"             # LU-5641
12447         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12448                 error "setting MDS group failed"                # LU-5641
12449
12450         declare -a identity_old
12451
12452         for ((num = 1; num <= $MDSCOUNT; num++)); do
12453                 switch_identity $num true || identity_old[$num]=$?
12454         done
12455
12456         SAVE_UMASK=$(umask)
12457         umask 0022
12458         mkdir -p $DIR/$tdir
12459         cd $DIR/$tdir
12460
12461         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12462         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12463         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12464         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12465         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12466         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12467         if ! id -u $ACLNBD ||
12468            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12469                 ACLNBD="nfsnobody"
12470                 if ! id -u $ACLNBD; then
12471                         ACLNBD=""
12472                 fi
12473         fi
12474         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12475                 add_group $(id -u $ACLNBD) $ACLNBD
12476                 if ! getent group $ACLNBD; then
12477                         ACLNBD=""
12478                 fi
12479         fi
12480         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12481            [[ -n "$ACLNBD" ]] && which setfattr; then
12482                 run_acl_subtest permissions_xattr \
12483                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12484         elif [[ -z "$ACLNBD" ]]; then
12485                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12486         else
12487                 echo "skip 'permission_xattr' test - missing setfattr command"
12488         fi
12489         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12490
12491         # inheritance test got from HP
12492         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12493         chmod +x make-tree || error "chmod +x failed"
12494         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12495         rm -f make-tree
12496
12497         echo "LU-974 ignore umask when acl is enabled..."
12498         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12499         if [ $MDSCOUNT -ge 2 ]; then
12500                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12501         fi
12502
12503         echo "LU-2561 newly created file is same size as directory..."
12504         if [ "$mds1_FSTYPE" != "zfs" ]; then
12505                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12506         else
12507                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12508         fi
12509
12510         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12511
12512         cd $SAVE_PWD
12513         umask $SAVE_UMASK
12514
12515         for ((num = 1; num <= $MDSCOUNT; num++)); do
12516                 if [[ "${identity_old[$num]}" == 1 ]]; then
12517                         switch_identity $num false || identity_old[$num]=$?
12518                 fi
12519         done
12520 }
12521 run_test 103a "acl test"
12522
12523 test_103b() {
12524         declare -a pids
12525         local U
12526
12527         stack_trap "rm -f $DIR/$tfile.*"
12528         for U in {0..511}; do
12529                 {
12530                 local O=$(printf "%04o" $U)
12531
12532                 umask $(printf "%04o" $((511 ^ $O)))
12533                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12534                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12535
12536                 (( $S == ($O & 0666) )) ||
12537                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12538
12539                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12540                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12541                 (( $S == ($O & 0666) )) ||
12542                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12543
12544                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12545                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12546                 (( $S == ($O & 0666) )) ||
12547                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12548                 rm -f $DIR/$tfile.[smp]$0
12549                 } &
12550                 local pid=$!
12551
12552                 # limit the concurrently running threads to 64. LU-11878
12553                 local idx=$((U % 64))
12554                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12555                 pids[idx]=$pid
12556         done
12557         wait
12558 }
12559 run_test 103b "umask lfs setstripe"
12560
12561 test_103c() {
12562         mkdir -p $DIR/$tdir
12563         cp -rp $DIR/$tdir $DIR/$tdir.bak
12564
12565         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12566                 error "$DIR/$tdir shouldn't contain default ACL"
12567         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12568                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12569         true
12570 }
12571 run_test 103c "'cp -rp' won't set empty acl"
12572
12573 test_103e() {
12574         local numacl
12575         local fileacl
12576         local saved_debug=$($LCTL get_param -n debug)
12577
12578         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12579                 skip "MDS needs to be at least 2.14.52"
12580
12581         large_xattr_enabled || skip_env "ea_inode feature disabled"
12582
12583         mkdir -p $DIR/$tdir
12584         # add big LOV EA to cause reply buffer overflow earlier
12585         $LFS setstripe -C 1000 $DIR/$tdir
12586         lctl set_param mdc.*-mdc*.stats=clear
12587
12588         $LCTL set_param debug=0
12589         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12590         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12591
12592         # add a large number of default ACLs (expect 8000+ for 2.13+)
12593         for U in {2..7000}; do
12594                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12595                         error "Able to add just $U default ACLs"
12596         done
12597         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12598         echo "$numacl default ACLs created"
12599
12600         stat $DIR/$tdir || error "Cannot stat directory"
12601         # check file creation
12602         touch $DIR/$tdir/$tfile ||
12603                 error "failed to create $tfile with $numacl default ACLs"
12604         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12605         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12606         echo "$fileacl ACLs were inherited"
12607         (( $fileacl == $numacl )) ||
12608                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12609         # check that new ACLs creation adds new ACLs to inherited ACLs
12610         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12611                 error "Cannot set new ACL"
12612         numacl=$((numacl + 1))
12613         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12614         (( $fileacl == $numacl )) ||
12615                 error "failed to add new ACL: $fileacl != $numacl as expected"
12616         # adds more ACLs to a file to reach their maximum at 8000+
12617         numacl=0
12618         for U in {20000..25000}; do
12619                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12620                 numacl=$((numacl + 1))
12621         done
12622         echo "Added $numacl more ACLs to the file"
12623         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12624         echo "Total $fileacl ACLs in file"
12625         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12626         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12627         rmdir $DIR/$tdir || error "Cannot remove directory"
12628 }
12629 run_test 103e "inheritance of big amount of default ACLs"
12630
12631 test_103f() {
12632         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12633                 skip "MDS needs to be at least 2.14.51"
12634
12635         large_xattr_enabled || skip_env "ea_inode feature disabled"
12636
12637         # enable changelog to consume more internal MDD buffers
12638         changelog_register
12639
12640         mkdir -p $DIR/$tdir
12641         # add big LOV EA
12642         $LFS setstripe -C 1000 $DIR/$tdir
12643         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12644         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12645         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12646         rmdir $DIR/$tdir || error "Cannot remove directory"
12647 }
12648 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12649
12650 test_104a() {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652
12653         touch $DIR/$tfile
12654         lfs df || error "lfs df failed"
12655         lfs df -ih || error "lfs df -ih failed"
12656         lfs df -h $DIR || error "lfs df -h $DIR failed"
12657         lfs df -i $DIR || error "lfs df -i $DIR failed"
12658         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12659         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12660
12661         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12662         lctl --device %$OSC deactivate
12663         lfs df || error "lfs df with deactivated OSC failed"
12664         lctl --device %$OSC activate
12665         # wait the osc back to normal
12666         wait_osc_import_ready client ost
12667
12668         lfs df || error "lfs df with reactivated OSC failed"
12669         rm -f $DIR/$tfile
12670 }
12671 run_test 104a "lfs df [-ih] [path] test ========================="
12672
12673 test_104b() {
12674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12675         [ $RUNAS_ID -eq $UID ] &&
12676                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12677
12678         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12679                         grep "Permission denied" | wc -l)))
12680         if [ $denied_cnt -ne 0 ]; then
12681                 error "lfs check servers test failed"
12682         fi
12683 }
12684 run_test 104b "$RUNAS lfs check servers test ===================="
12685
12686 #
12687 # Verify $1 is within range of $2.
12688 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12689 # $1 is <= 2% of $2. Else Fail.
12690 #
12691 value_in_range() {
12692         # Strip all units (M, G, T)
12693         actual=$(echo $1 | tr -d A-Z)
12694         expect=$(echo $2 | tr -d A-Z)
12695
12696         expect_lo=$(($expect * 98 / 100)) # 2% below
12697         expect_hi=$(($expect * 102 / 100)) # 2% above
12698
12699         # permit 2% drift above and below
12700         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12701 }
12702
12703 test_104c() {
12704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12705         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12706
12707         local ost_param="osd-zfs.$FSNAME-OST0000."
12708         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12709         local ofacets=$(get_facets OST)
12710         local mfacets=$(get_facets MDS)
12711         local saved_ost_blocks=
12712         local saved_mdt_blocks=
12713
12714         echo "Before recordsize change"
12715         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12716         df=($(df -h | grep "$MOUNT"$))
12717
12718         # For checking.
12719         echo "lfs output : ${lfs_df[*]}"
12720         echo "df  output : ${df[*]}"
12721
12722         for facet in ${ofacets//,/ }; do
12723                 if [ -z $saved_ost_blocks ]; then
12724                         saved_ost_blocks=$(do_facet $facet \
12725                                 lctl get_param -n $ost_param.blocksize)
12726                         echo "OST Blocksize: $saved_ost_blocks"
12727                 fi
12728                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12729                 do_facet $facet zfs set recordsize=32768 $ost
12730         done
12731
12732         # BS too small. Sufficient for functional testing.
12733         for facet in ${mfacets//,/ }; do
12734                 if [ -z $saved_mdt_blocks ]; then
12735                         saved_mdt_blocks=$(do_facet $facet \
12736                                 lctl get_param -n $mdt_param.blocksize)
12737                         echo "MDT Blocksize: $saved_mdt_blocks"
12738                 fi
12739                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12740                 do_facet $facet zfs set recordsize=32768 $mdt
12741         done
12742
12743         # Give new values chance to reflect change
12744         sleep 2
12745
12746         echo "After recordsize change"
12747         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12748         df_after=($(df -h | grep "$MOUNT"$))
12749
12750         # For checking.
12751         echo "lfs output : ${lfs_df_after[*]}"
12752         echo "df  output : ${df_after[*]}"
12753
12754         # Verify lfs df
12755         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12756                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12757         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12758                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12759         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12760                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12761
12762         # Verify df
12763         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12764                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12765         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12766                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12767         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12768                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12769
12770         # Restore MDT recordize back to original
12771         for facet in ${mfacets//,/ }; do
12772                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12773                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12774         done
12775
12776         # Restore OST recordize back to original
12777         for facet in ${ofacets//,/ }; do
12778                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12779                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12780         done
12781
12782         return 0
12783 }
12784 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12785
12786 test_104d() {
12787         (( $RUNAS_ID != $UID )) ||
12788                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12789
12790         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12791                 skip "lustre version doesn't support lctl dl with non-root"
12792
12793         # debugfs only allows root users to access files, so the
12794         # previous move of the "devices" file to debugfs broke
12795         # "lctl dl" for non-root users. The LU-9680 Netlink
12796         # interface again allows non-root users to list devices.
12797         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12798                 error "lctl dl doesn't work for non root"
12799
12800         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12801         [ "$ost_count" -eq $OSTCOUNT ]  ||
12802                 error "lctl dl reports wrong number of OST devices"
12803
12804         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12805         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12806                 error "lctl dl reports wrong number of MDT devices"
12807 }
12808 run_test 104d "$RUNAS lctl dl test"
12809
12810 test_105a() {
12811         # doesn't work on 2.4 kernels
12812         touch $DIR/$tfile
12813         if $(flock_is_enabled); then
12814                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12815         else
12816                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12817         fi
12818         rm -f $DIR/$tfile
12819 }
12820 run_test 105a "flock when mounted without -o flock test ========"
12821
12822 test_105b() {
12823         touch $DIR/$tfile
12824         if $(flock_is_enabled); then
12825                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12826         else
12827                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12828         fi
12829         rm -f $DIR/$tfile
12830 }
12831 run_test 105b "fcntl when mounted without -o flock test ========"
12832
12833 test_105c() {
12834         touch $DIR/$tfile
12835         if $(flock_is_enabled); then
12836                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12837         else
12838                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12839         fi
12840         rm -f $DIR/$tfile
12841 }
12842 run_test 105c "lockf when mounted without -o flock test"
12843
12844 test_105d() { # bug 15924
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846
12847         test_mkdir $DIR/$tdir
12848         flock_is_enabled || skip_env "mount w/o flock enabled"
12849         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12850         $LCTL set_param fail_loc=0x80000315
12851         flocks_test 2 $DIR/$tdir
12852 }
12853 run_test 105d "flock race (should not freeze) ========"
12854
12855 test_105e() { # bug 22660 && 22040
12856         flock_is_enabled || skip_env "mount w/o flock enabled"
12857
12858         touch $DIR/$tfile
12859         flocks_test 3 $DIR/$tfile
12860 }
12861 run_test 105e "Two conflicting flocks from same process"
12862
12863 test_106() { #bug 10921
12864         test_mkdir $DIR/$tdir
12865         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12866         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12867 }
12868 run_test 106 "attempt exec of dir followed by chown of that dir"
12869
12870 test_107() {
12871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12872
12873         CDIR=`pwd`
12874         local file=core
12875
12876         cd $DIR
12877         rm -f $file
12878
12879         local save_pattern=$(sysctl -n kernel.core_pattern)
12880         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12881         sysctl -w kernel.core_pattern=$file
12882         sysctl -w kernel.core_uses_pid=0
12883
12884         ulimit -c unlimited
12885         sleep 60 &
12886         SLEEPPID=$!
12887
12888         sleep 1
12889
12890         kill -s 11 $SLEEPPID
12891         wait $SLEEPPID
12892         if [ -e $file ]; then
12893                 size=`stat -c%s $file`
12894                 [ $size -eq 0 ] && error "Fail to create core file $file"
12895         else
12896                 error "Fail to create core file $file"
12897         fi
12898         rm -f $file
12899         sysctl -w kernel.core_pattern=$save_pattern
12900         sysctl -w kernel.core_uses_pid=$save_uses_pid
12901         cd $CDIR
12902 }
12903 run_test 107 "Coredump on SIG"
12904
12905 test_110() {
12906         test_mkdir $DIR/$tdir
12907         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12908         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12909                 error "mkdir with 256 char should fail, but did not"
12910         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12911                 error "create with 255 char failed"
12912         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12913                 error "create with 256 char should fail, but did not"
12914
12915         ls -l $DIR/$tdir
12916         rm -rf $DIR/$tdir
12917 }
12918 run_test 110 "filename length checking"
12919
12920 test_116a() { # was previously test_116()
12921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12923         remote_mds_nodsh && skip "remote MDS with nodsh"
12924
12925         echo -n "Free space priority "
12926         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12927                 head -n1
12928         declare -a AVAIL
12929         free_min_max
12930
12931         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12932         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12933         stack_trap simple_cleanup_common
12934
12935         # Check if we need to generate uneven OSTs
12936         test_mkdir -p $DIR/$tdir/OST${MINI}
12937         local FILL=$((MINV / 4))
12938         local DIFF=$((MAXV - MINV))
12939         local DIFF2=$((DIFF * 100 / MINV))
12940
12941         local threshold=$(do_facet $SINGLEMDS \
12942                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12943         threshold=${threshold%%%}
12944         echo -n "Check for uneven OSTs: "
12945         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12946
12947         if [[ $DIFF2 -gt $threshold ]]; then
12948                 echo "ok"
12949                 echo "Don't need to fill OST$MINI"
12950         else
12951                 # generate uneven OSTs. Write 2% over the QOS threshold value
12952                 echo "no"
12953                 DIFF=$((threshold - DIFF2 + 2))
12954                 DIFF2=$((MINV * DIFF / 100))
12955                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12956                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12957                         error "setstripe failed"
12958                 DIFF=$((DIFF2 / 2048))
12959                 i=0
12960                 while [ $i -lt $DIFF ]; do
12961                         i=$((i + 1))
12962                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12963                                 bs=2M count=1 2>/dev/null
12964                         echo -n .
12965                 done
12966                 echo .
12967                 sync
12968                 sleep_maxage
12969                 free_min_max
12970         fi
12971
12972         DIFF=$((MAXV - MINV))
12973         DIFF2=$((DIFF * 100 / MINV))
12974         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12975         if [ $DIFF2 -gt $threshold ]; then
12976                 echo "ok"
12977         else
12978                 skip "QOS imbalance criteria not met"
12979         fi
12980
12981         MINI1=$MINI
12982         MINV1=$MINV
12983         MAXI1=$MAXI
12984         MAXV1=$MAXV
12985
12986         # now fill using QOS
12987         $LFS setstripe -c 1 $DIR/$tdir
12988         FILL=$((FILL / 200))
12989         if [ $FILL -gt 600 ]; then
12990                 FILL=600
12991         fi
12992         echo "writing $FILL files to QOS-assigned OSTs"
12993         i=0
12994         while [ $i -lt $FILL ]; do
12995                 i=$((i + 1))
12996                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12997                         count=1 2>/dev/null
12998                 echo -n .
12999         done
13000         echo "wrote $i 200k files"
13001         sync
13002         sleep_maxage
13003
13004         echo "Note: free space may not be updated, so measurements might be off"
13005         free_min_max
13006         DIFF2=$((MAXV - MINV))
13007         echo "free space delta: orig $DIFF final $DIFF2"
13008         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13009         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13010         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13011         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13012         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13013         if [[ $DIFF -gt 0 ]]; then
13014                 FILL=$((DIFF2 * 100 / DIFF - 100))
13015                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13016         fi
13017
13018         # Figure out which files were written where
13019         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13020                awk '/'$MINI1': / {print $2; exit}')
13021         echo $UUID
13022         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13023         echo "$MINC files created on smaller OST $MINI1"
13024         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13025                awk '/'$MAXI1': / {print $2; exit}')
13026         echo $UUID
13027         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13028         echo "$MAXC files created on larger OST $MAXI1"
13029         if [[ $MINC -gt 0 ]]; then
13030                 FILL=$((MAXC * 100 / MINC - 100))
13031                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13032         fi
13033         [[ $MAXC -gt $MINC ]] ||
13034                 error_ignore LU-9 "stripe QOS didn't balance free space"
13035 }
13036 run_test 116a "stripe QOS: free space balance ==================="
13037
13038 test_116b() { # LU-2093
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040         remote_mds_nodsh && skip "remote MDS with nodsh"
13041
13042 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13043         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13044                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13045         [ -z "$old_rr" ] && skip "no QOS"
13046         do_facet $SINGLEMDS lctl set_param \
13047                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13048         mkdir -p $DIR/$tdir
13049         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13050         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13051         do_facet $SINGLEMDS lctl set_param fail_loc=0
13052         rm -rf $DIR/$tdir
13053         do_facet $SINGLEMDS lctl set_param \
13054                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13055 }
13056 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13057
13058 test_117() # bug 10891
13059 {
13060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13061
13062         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13063         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13064         lctl set_param fail_loc=0x21e
13065         > $DIR/$tfile || error "truncate failed"
13066         lctl set_param fail_loc=0
13067         echo "Truncate succeeded."
13068         rm -f $DIR/$tfile
13069 }
13070 run_test 117 "verify osd extend =========="
13071
13072 NO_SLOW_RESENDCOUNT=4
13073 export OLD_RESENDCOUNT=""
13074 set_resend_count () {
13075         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13076         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13077         lctl set_param -n $PROC_RESENDCOUNT $1
13078         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13079 }
13080
13081 # for reduce test_118* time (b=14842)
13082 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13083
13084 # Reset async IO behavior after error case
13085 reset_async() {
13086         FILE=$DIR/reset_async
13087
13088         # Ensure all OSCs are cleared
13089         $LFS setstripe -c -1 $FILE
13090         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13091         sync
13092         rm $FILE
13093 }
13094
13095 test_118a() #bug 11710
13096 {
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098
13099         reset_async
13100
13101         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13102         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13103         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13104
13105         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13106                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13107                 return 1;
13108         fi
13109         rm -f $DIR/$tfile
13110 }
13111 run_test 118a "verify O_SYNC works =========="
13112
13113 test_118b()
13114 {
13115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13116         remote_ost_nodsh && skip "remote OST with nodsh"
13117
13118         reset_async
13119
13120         #define OBD_FAIL_SRV_ENOENT 0x217
13121         set_nodes_failloc "$(osts_nodes)" 0x217
13122         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13123         RC=$?
13124         set_nodes_failloc "$(osts_nodes)" 0
13125         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13126         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13127                     grep -c writeback)
13128
13129         if [[ $RC -eq 0 ]]; then
13130                 error "Must return error due to dropped pages, rc=$RC"
13131                 return 1;
13132         fi
13133
13134         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13135                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13136                 return 1;
13137         fi
13138
13139         echo "Dirty pages not leaked on ENOENT"
13140
13141         # Due to the above error the OSC will issue all RPCs syncronously
13142         # until a subsequent RPC completes successfully without error.
13143         $MULTIOP $DIR/$tfile Ow4096yc
13144         rm -f $DIR/$tfile
13145
13146         return 0
13147 }
13148 run_test 118b "Reclaim dirty pages on fatal error =========="
13149
13150 test_118c()
13151 {
13152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13153
13154         # for 118c, restore the original resend count, LU-1940
13155         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13156                                 set_resend_count $OLD_RESENDCOUNT
13157         remote_ost_nodsh && skip "remote OST with nodsh"
13158
13159         reset_async
13160
13161         #define OBD_FAIL_OST_EROFS               0x216
13162         set_nodes_failloc "$(osts_nodes)" 0x216
13163
13164         # multiop should block due to fsync until pages are written
13165         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13166         MULTIPID=$!
13167         sleep 1
13168
13169         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13170                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13171         fi
13172
13173         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13174                     grep -c writeback)
13175         if [[ $WRITEBACK -eq 0 ]]; then
13176                 error "No page in writeback, writeback=$WRITEBACK"
13177         fi
13178
13179         set_nodes_failloc "$(osts_nodes)" 0
13180         wait $MULTIPID
13181         RC=$?
13182         if [[ $RC -ne 0 ]]; then
13183                 error "Multiop fsync failed, rc=$RC"
13184         fi
13185
13186         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13187         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13188                     grep -c writeback)
13189         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13190                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13191         fi
13192
13193         rm -f $DIR/$tfile
13194         echo "Dirty pages flushed via fsync on EROFS"
13195         return 0
13196 }
13197 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13198
13199 # continue to use small resend count to reduce test_118* time (b=14842)
13200 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13201
13202 test_118d()
13203 {
13204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13205         remote_ost_nodsh && skip "remote OST with nodsh"
13206
13207         reset_async
13208
13209         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13210         set_nodes_failloc "$(osts_nodes)" 0x214
13211         # multiop should block due to fsync until pages are written
13212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13213         MULTIPID=$!
13214         sleep 1
13215
13216         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13217                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13218         fi
13219
13220         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13221                     grep -c writeback)
13222         if [[ $WRITEBACK -eq 0 ]]; then
13223                 error "No page in writeback, writeback=$WRITEBACK"
13224         fi
13225
13226         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13227         set_nodes_failloc "$(osts_nodes)" 0
13228
13229         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13230         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13231                     grep -c writeback)
13232         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13233                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13234         fi
13235
13236         rm -f $DIR/$tfile
13237         echo "Dirty pages gaurenteed flushed via fsync"
13238         return 0
13239 }
13240 run_test 118d "Fsync validation inject a delay of the bulk =========="
13241
13242 test_118f() {
13243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13244
13245         reset_async
13246
13247         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13248         lctl set_param fail_loc=0x8000040a
13249
13250         # Should simulate EINVAL error which is fatal
13251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13252         RC=$?
13253         if [[ $RC -eq 0 ]]; then
13254                 error "Must return error due to dropped pages, rc=$RC"
13255         fi
13256
13257         lctl set_param fail_loc=0x0
13258
13259         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13260         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13261         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13262                     grep -c writeback)
13263         if [[ $LOCKED -ne 0 ]]; then
13264                 error "Locked pages remain in cache, locked=$LOCKED"
13265         fi
13266
13267         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13268                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13269         fi
13270
13271         rm -f $DIR/$tfile
13272         echo "No pages locked after fsync"
13273
13274         reset_async
13275         return 0
13276 }
13277 run_test 118f "Simulate unrecoverable OSC side error =========="
13278
13279 test_118g() {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281
13282         reset_async
13283
13284         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13285         lctl set_param fail_loc=0x406
13286
13287         # simulate local -ENOMEM
13288         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13289         RC=$?
13290
13291         lctl set_param fail_loc=0
13292         if [[ $RC -eq 0 ]]; then
13293                 error "Must return error due to dropped pages, rc=$RC"
13294         fi
13295
13296         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13299                         grep -c writeback)
13300         if [[ $LOCKED -ne 0 ]]; then
13301                 error "Locked pages remain in cache, locked=$LOCKED"
13302         fi
13303
13304         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13305                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13306         fi
13307
13308         rm -f $DIR/$tfile
13309         echo "No pages locked after fsync"
13310
13311         reset_async
13312         return 0
13313 }
13314 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13315
13316 test_118h() {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         remote_ost_nodsh && skip "remote OST with nodsh"
13319
13320         reset_async
13321
13322         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13323         set_nodes_failloc "$(osts_nodes)" 0x20e
13324         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13326         RC=$?
13327
13328         set_nodes_failloc "$(osts_nodes)" 0
13329         if [[ $RC -eq 0 ]]; then
13330                 error "Must return error due to dropped pages, rc=$RC"
13331         fi
13332
13333         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13334         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13335         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13336                     grep -c writeback)
13337         if [[ $LOCKED -ne 0 ]]; then
13338                 error "Locked pages remain in cache, locked=$LOCKED"
13339         fi
13340
13341         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13342                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13343         fi
13344
13345         rm -f $DIR/$tfile
13346         echo "No pages locked after fsync"
13347
13348         return 0
13349 }
13350 run_test 118h "Verify timeout in handling recoverables errors  =========="
13351
13352 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13353
13354 test_118i() {
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356         remote_ost_nodsh && skip "remote OST with nodsh"
13357
13358         reset_async
13359
13360         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13361         set_nodes_failloc "$(osts_nodes)" 0x20e
13362
13363         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13364         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13365         PID=$!
13366         sleep 5
13367         set_nodes_failloc "$(osts_nodes)" 0
13368
13369         wait $PID
13370         RC=$?
13371         if [[ $RC -ne 0 ]]; then
13372                 error "got error, but should be not, rc=$RC"
13373         fi
13374
13375         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13376         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13377         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13378         if [[ $LOCKED -ne 0 ]]; then
13379                 error "Locked pages remain in cache, locked=$LOCKED"
13380         fi
13381
13382         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13383                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13384         fi
13385
13386         rm -f $DIR/$tfile
13387         echo "No pages locked after fsync"
13388
13389         return 0
13390 }
13391 run_test 118i "Fix error before timeout in recoverable error  =========="
13392
13393 [ "$SLOW" = "no" ] && set_resend_count 4
13394
13395 test_118j() {
13396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13397         remote_ost_nodsh && skip "remote OST with nodsh"
13398
13399         reset_async
13400
13401         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13402         set_nodes_failloc "$(osts_nodes)" 0x220
13403
13404         # return -EIO from OST
13405         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13406         RC=$?
13407         set_nodes_failloc "$(osts_nodes)" 0x0
13408         if [[ $RC -eq 0 ]]; then
13409                 error "Must return error due to dropped pages, rc=$RC"
13410         fi
13411
13412         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13415         if [[ $LOCKED -ne 0 ]]; then
13416                 error "Locked pages remain in cache, locked=$LOCKED"
13417         fi
13418
13419         # in recoverable error on OST we want resend and stay until it finished
13420         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13421                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13422         fi
13423
13424         rm -f $DIR/$tfile
13425         echo "No pages locked after fsync"
13426
13427         return 0
13428 }
13429 run_test 118j "Simulate unrecoverable OST side error =========="
13430
13431 test_118k()
13432 {
13433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13434         remote_ost_nodsh && skip "remote OSTs with nodsh"
13435
13436         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13437         set_nodes_failloc "$(osts_nodes)" 0x20e
13438         test_mkdir $DIR/$tdir
13439
13440         for ((i=0;i<10;i++)); do
13441                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13442                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13443                 SLEEPPID=$!
13444                 sleep 0.500s
13445                 kill $SLEEPPID
13446                 wait $SLEEPPID
13447         done
13448
13449         set_nodes_failloc "$(osts_nodes)" 0
13450         rm -rf $DIR/$tdir
13451 }
13452 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13453
13454 test_118l() # LU-646
13455 {
13456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13457
13458         test_mkdir $DIR/$tdir
13459         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13460         rm -rf $DIR/$tdir
13461 }
13462 run_test 118l "fsync dir"
13463
13464 test_118m() # LU-3066
13465 {
13466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13467
13468         test_mkdir $DIR/$tdir
13469         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13470         rm -rf $DIR/$tdir
13471 }
13472 run_test 118m "fdatasync dir ========="
13473
13474 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13475
13476 test_118n()
13477 {
13478         local begin
13479         local end
13480
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482         remote_ost_nodsh && skip "remote OSTs with nodsh"
13483
13484         # Sleep to avoid a cached response.
13485         #define OBD_STATFS_CACHE_SECONDS 1
13486         sleep 2
13487
13488         # Inject a 10 second delay in the OST_STATFS handler.
13489         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13490         set_nodes_failloc "$(osts_nodes)" 0x242
13491
13492         begin=$SECONDS
13493         stat --file-system $MOUNT > /dev/null
13494         end=$SECONDS
13495
13496         set_nodes_failloc "$(osts_nodes)" 0
13497
13498         if ((end - begin > 20)); then
13499             error "statfs took $((end - begin)) seconds, expected 10"
13500         fi
13501 }
13502 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13503
13504 test_119a() # bug 11737
13505 {
13506         BSIZE=$((512 * 1024))
13507         directio write $DIR/$tfile 0 1 $BSIZE
13508         # We ask to read two blocks, which is more than a file size.
13509         # directio will indicate an error when requested and actual
13510         # sizes aren't equeal (a normal situation in this case) and
13511         # print actual read amount.
13512         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13513         if [ "$NOB" != "$BSIZE" ]; then
13514                 error "read $NOB bytes instead of $BSIZE"
13515         fi
13516         rm -f $DIR/$tfile
13517 }
13518 run_test 119a "Short directIO read must return actual read amount"
13519
13520 test_119b() # bug 11737
13521 {
13522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13523
13524         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13526         sync
13527         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13528                 error "direct read failed"
13529         rm -f $DIR/$tfile
13530 }
13531 run_test 119b "Sparse directIO read must return actual read amount"
13532
13533 test_119c() # bug 13099
13534 {
13535         BSIZE=1048576
13536         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13537         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13538         rm -f $DIR/$tfile
13539 }
13540 run_test 119c "Testing for direct read hitting hole"
13541
13542 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13543 # Maloo test history
13544
13545 test_119e()
13546 {
13547         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13548                 skip "Need server version at least 2.15.58"
13549         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13550
13551         local stripe_size=$((1024 * 1024)) #1 MiB
13552         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13553         local file_size=$((25 * stripe_size))
13554         local bsizes
13555
13556         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13557         stack_trap "rm -f $DIR/$tfile*"
13558
13559         # Just a bit bigger than the largest size in the test set below
13560         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13561                 error "buffered i/o to create file failed"
13562
13563         # trivial test of unaligned DIO
13564         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13565                 iflag=direct oflag=direct ||
13566                 error "trivial unaligned dio failed"
13567
13568         # Test of disabling unaligned DIO support
13569         $LCTL set_param llite.*.unaligned_dio=0
13570         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13571         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13572         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13573                 iflag=direct oflag=direct &&
13574                 error "unaligned dio succeeded when disabled"
13575         $LCTL set_param llite.*.unaligned_dio=1
13576
13577         # Clean up before next part of test
13578         rm -f $DIR/$tfile.2
13579
13580         if zfs_or_rotational; then
13581                 # DIO on ZFS can take up to 2 seconds per IO
13582                 # rotational is better, but still slow.
13583                 # Limit testing on those media to larger sizes
13584                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13585                         $((stripe_size + 1024))"
13586         else
13587                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13588                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13589                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13590                         $((stripe_size - 1)) $stripe_size \
13591                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13592                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13593         fi
13594
13595         for bs in $bsizes; do
13596                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13597                 echo "Read/write with DIO at size $bs"
13598                 # Read and write with DIO from source to dest
13599                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13600                         iflag=direct oflag=direct ||
13601                         error "dio failed"
13602
13603                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13604                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13605                         error "size incorrect, file copy read/write bsize: $bs"
13606                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13607                         error "files differ, bsize $bs"
13608                 rm -f $DIR/$tfile.2
13609         done
13610 }
13611 run_test 119e "Basic tests of dio read and write at various sizes"
13612
13613 test_119f()
13614 {
13615         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13616
13617         local stripe_size=$((1024 * 1024)) #1 MiB
13618         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13619         local file_size=$((25 * stripe_size))
13620         local bsizes
13621
13622         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13623         stack_trap "rm -f $DIR/$tfile*"
13624
13625         # Just a bit bigger than the largest size in the test set below
13626         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13627                 error "buffered i/o to create file failed"
13628
13629         if zfs_or_rotational; then
13630                 # DIO on ZFS can take up to 2 seconds per IO
13631                 # rotational is better, but still slow.
13632                 # Limit testing on those media to larger sizes
13633                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13634                         $((stripe_size + 1024))"
13635         else
13636                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13637                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13638                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13639                         $((stripe_size - 1)) $stripe_size \
13640                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13641                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13642         fi
13643
13644         for bs in $bsizes; do
13645                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13646                 # Read and write with DIO from source to dest in two
13647                 # threads - should give correct copy of file
13648
13649                 echo "bs: $bs"
13650                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13651                         oflag=direct conv=notrunc &
13652                 pid_dio1=$!
13653                 # Note block size is different here for a more interesting race
13654                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13655                         iflag=direct oflag=direct conv=notrunc &
13656                 pid_dio2=$!
13657                 wait $pid_dio1
13658                 rc1=$?
13659                 wait $pid_dio2
13660                 rc2=$?
13661                 if (( rc1 != 0 )); then
13662                         error "dio copy 1 w/bsize $bs failed: $rc1"
13663                 fi
13664                 if (( rc2 != 0 )); then
13665                         error "dio copy 2 w/bsize $bs failed: $rc2"
13666                 fi
13667
13668
13669                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13670                         error "size incorrect, file copy read/write bsize: $bs"
13671                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13672                         error "files differ, bsize $bs"
13673                 rm -f $DIR/$tfile.2
13674         done
13675 }
13676 run_test 119f "dio vs dio race"
13677
13678 test_119g()
13679 {
13680         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13681
13682         local stripe_size=$((1024 * 1024)) #1 MiB
13683         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13684         local file_size=$((25 * stripe_size))
13685         local bsizes
13686
13687         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13688         stack_trap "rm -f $DIR/$tfile*"
13689
13690         # Just a bit bigger than the largest size in the test set below
13691         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13692                 error "buffered i/o to create file failed"
13693
13694         if zfs_or_rotational; then
13695                 # DIO on ZFS can take up to 2 seconds per IO
13696                 # rotational is better, but still slow.
13697                 # Limit testing on those media to larger sizes
13698                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13699                         $((stripe_size + 1024))"
13700         else
13701                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13702                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13703                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13704                         $((stripe_size - 1)) $stripe_size \
13705                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13706                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13707         fi
13708
13709         for bs in $bsizes; do
13710                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13711                 echo "bs: $bs"
13712                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13713                         oflag=direct conv=notrunc &
13714                 pid_dio1=$!
13715                 # Buffered I/O with similar but not the same block size
13716                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13717                 pid_bio2=$!
13718                 wait $pid_dio1
13719                 rc1=$?
13720                 wait $pid_bio2
13721                 rc2=$?
13722                 if (( rc1 != 0 )); then
13723                         error "dio copy 1 w/bsize $bs failed: $rc1"
13724                 fi
13725                 if (( rc2 != 0 )); then
13726                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13727                 fi
13728
13729                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13730                         error "size incorrect"
13731                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13732                         error "files differ, bsize $bs"
13733                 rm -f $DIR/$tfile.2
13734         done
13735 }
13736 run_test 119g "dio vs buffered I/O race"
13737
13738 test_119h()
13739 {
13740         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13741
13742         local stripe_size=$((1024 * 1024)) #1 MiB
13743         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13744         local file_size=$((25 * stripe_size))
13745         local bsizes
13746
13747         stack_trap "rm -f $DIR/$tfile.*"
13748
13749         if zfs_or_rotational; then
13750                 # DIO on ZFS can take up to 2 seconds per IO
13751                 # rotational is better, but still slow.
13752                 # Limit testing on those media to larger sizes
13753                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13754                         $((stripe_size + 1024))"
13755         else
13756                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13757                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13758                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13759                         $((stripe_size - 1)) $stripe_size \
13760                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13761                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13762         fi
13763
13764         for bs in $bsizes; do
13765                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13766                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13767                 echo "unaligned writes of blocksize: $bs"
13768                 # Write a file with unaligned DIO and regular DIO, and compare
13769                 # them
13770                 # with 'u', multiop randomly unaligns the io from the buffer
13771                 $MULTIOP $DIR/$tfile.1 \
13772                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13773                         error "multiop memory unaligned write failed, $bs"
13774                 $MULTIOP $DIR/$tfile.2 \
13775                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13776                         error "multiop memory aligned write failed, $bs"
13777
13778                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13779                         error "files differ, bsize $bs"
13780                 rm -f $DIR/$tfile.*
13781         done
13782
13783         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13784         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13785                 error "dd to create source file for read failed"
13786
13787         # Just a few quick tests to make sure unaligned DIO reads don't crash
13788         for bs in $bsizes; do
13789
13790                 echo "unaligned reads of blocksize: $bs"
13791                 # with 'u', multiop randomly unaligns the io from the buffer
13792                 $MULTIOP $DIR/$tfile.1 \
13793                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13794                         error "multiop memory unaligned read failed, $bs"
13795
13796         done
13797         rm -f $DIR/$tfile*
13798 }
13799 run_test 119h "basic tests of memory unaligned dio"
13800
13801 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13802 test_119i()
13803 {
13804         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13805         which aiocp || skip_env "no aiocp installed"
13806
13807         local stripe_size=$((1024 * 1024)) #1 MiB
13808         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13809         local file_size=$((25 * stripe_size))
13810         local bsizes
13811
13812         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13813         stack_trap "rm -f $DIR/$tfile.*"
13814
13815         # Just a bit bigger than the largest size in the test set below
13816         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13817                 error "buffered i/o to create file failed"
13818
13819         if zfs_or_rotational; then
13820                 # DIO on ZFS can take up to 2 seconds per IO
13821                 # rotational is better, but still slow.
13822                 # Limit testing on those media to larger sizes
13823                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13824                         $((stripe_size + 1024))"
13825         else
13826                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13827                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13828                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13829                         $((stripe_size - 1)) $stripe_size \
13830                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13831                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13832         fi
13833
13834         # Do page aligned and NOT page aligned AIO
13835         for align in 8 512 $((PAGE_SIZE)); do
13836         # Deliberately includes a few aligned sizes
13837         for bs in $bsizes; do
13838                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13839
13840                 echo "bs: $bs, align: $align, file_size $file_size"
13841                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13842                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13843                         error "unaligned aio failed, bs: $bs, align: $align"
13844
13845                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13846                         error "size incorrect"
13847                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13848                         error "files differ"
13849                 rm -f $DIR/$tfile.2
13850         done
13851         done
13852 }
13853 run_test 119i "test unaligned aio at varying sizes"
13854
13855 test_120a() {
13856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13857         remote_mds_nodsh && skip "remote MDS with nodsh"
13858         test_mkdir -i0 -c1 $DIR/$tdir
13859         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13860                 skip_env "no early lock cancel on server"
13861
13862         lru_resize_disable mdc
13863         lru_resize_disable osc
13864         cancel_lru_locks mdc
13865         # asynchronous object destroy at MDT could cause bl ast to client
13866         cancel_lru_locks osc
13867
13868         stat $DIR/$tdir > /dev/null
13869         can1=$(do_facet mds1 \
13870                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13871                awk '/ldlm_cancel/ {print $2}')
13872         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13873                awk '/ldlm_bl_callback/ {print $2}')
13874         test_mkdir -i0 -c1 $DIR/$tdir/d1
13875         can2=$(do_facet mds1 \
13876                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13877                awk '/ldlm_cancel/ {print $2}')
13878         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13879                awk '/ldlm_bl_callback/ {print $2}')
13880         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13881         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13882         lru_resize_enable mdc
13883         lru_resize_enable osc
13884 }
13885 run_test 120a "Early Lock Cancel: mkdir test"
13886
13887 test_120b() {
13888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13889         remote_mds_nodsh && skip "remote MDS with nodsh"
13890         test_mkdir $DIR/$tdir
13891         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13892                 skip_env "no early lock cancel on server"
13893
13894         lru_resize_disable mdc
13895         lru_resize_disable osc
13896         cancel_lru_locks mdc
13897         stat $DIR/$tdir > /dev/null
13898         can1=$(do_facet $SINGLEMDS \
13899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13900                awk '/ldlm_cancel/ {print $2}')
13901         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13902                awk '/ldlm_bl_callback/ {print $2}')
13903         touch $DIR/$tdir/f1
13904         can2=$(do_facet $SINGLEMDS \
13905                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13906                awk '/ldlm_cancel/ {print $2}')
13907         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13908                awk '/ldlm_bl_callback/ {print $2}')
13909         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13910         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13911         lru_resize_enable mdc
13912         lru_resize_enable osc
13913 }
13914 run_test 120b "Early Lock Cancel: create test"
13915
13916 test_120c() {
13917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13918         remote_mds_nodsh && skip "remote MDS with nodsh"
13919         test_mkdir -i0 -c1 $DIR/$tdir
13920         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13921                 skip "no early lock cancel on server"
13922
13923         lru_resize_disable mdc
13924         lru_resize_disable osc
13925         test_mkdir -i0 -c1 $DIR/$tdir/d1
13926         test_mkdir -i0 -c1 $DIR/$tdir/d2
13927         touch $DIR/$tdir/d1/f1
13928         cancel_lru_locks mdc
13929         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13930         can1=$(do_facet mds1 \
13931                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13932                awk '/ldlm_cancel/ {print $2}')
13933         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13934                awk '/ldlm_bl_callback/ {print $2}')
13935         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13936         can2=$(do_facet mds1 \
13937                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13938                awk '/ldlm_cancel/ {print $2}')
13939         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13940                awk '/ldlm_bl_callback/ {print $2}')
13941         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13942         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13943         lru_resize_enable mdc
13944         lru_resize_enable osc
13945 }
13946 run_test 120c "Early Lock Cancel: link test"
13947
13948 test_120d() {
13949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13950         remote_mds_nodsh && skip "remote MDS with nodsh"
13951         test_mkdir -i0 -c1 $DIR/$tdir
13952         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13953                 skip_env "no early lock cancel on server"
13954
13955         lru_resize_disable mdc
13956         lru_resize_disable osc
13957         touch $DIR/$tdir
13958         cancel_lru_locks mdc
13959         stat $DIR/$tdir > /dev/null
13960         can1=$(do_facet mds1 \
13961                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13962                awk '/ldlm_cancel/ {print $2}')
13963         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13964                awk '/ldlm_bl_callback/ {print $2}')
13965         chmod a+x $DIR/$tdir
13966         can2=$(do_facet mds1 \
13967                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13968                awk '/ldlm_cancel/ {print $2}')
13969         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13970                awk '/ldlm_bl_callback/ {print $2}')
13971         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13972         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13973         lru_resize_enable mdc
13974         lru_resize_enable osc
13975 }
13976 run_test 120d "Early Lock Cancel: setattr test"
13977
13978 test_120e() {
13979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13980         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13981                 skip_env "no early lock cancel on server"
13982         remote_mds_nodsh && skip "remote MDS with nodsh"
13983
13984         local dlmtrace_set=false
13985
13986         test_mkdir -i0 -c1 $DIR/$tdir
13987         lru_resize_disable mdc
13988         lru_resize_disable osc
13989         ! $LCTL get_param debug | grep -q dlmtrace &&
13990                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13991         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13992         cancel_lru_locks mdc
13993         cancel_lru_locks osc
13994         dd if=$DIR/$tdir/f1 of=/dev/null
13995         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13996         # XXX client can not do early lock cancel of OST lock
13997         # during unlink (LU-4206), so cancel osc lock now.
13998         sleep 2
13999         cancel_lru_locks osc
14000         can1=$(do_facet mds1 \
14001                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14002                awk '/ldlm_cancel/ {print $2}')
14003         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14004                awk '/ldlm_bl_callback/ {print $2}')
14005         unlink $DIR/$tdir/f1
14006         sleep 5
14007         can2=$(do_facet mds1 \
14008                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14009                awk '/ldlm_cancel/ {print $2}')
14010         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14011                awk '/ldlm_bl_callback/ {print $2}')
14012         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14013                 $LCTL dk $TMP/cancel.debug.txt
14014         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14015                 $LCTL dk $TMP/blocking.debug.txt
14016         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14017         lru_resize_enable mdc
14018         lru_resize_enable osc
14019 }
14020 run_test 120e "Early Lock Cancel: unlink test"
14021
14022 test_120f() {
14023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14024         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14025                 skip_env "no early lock cancel on server"
14026         remote_mds_nodsh && skip "remote MDS with nodsh"
14027
14028         test_mkdir -i0 -c1 $DIR/$tdir
14029         lru_resize_disable mdc
14030         lru_resize_disable osc
14031         test_mkdir -i0 -c1 $DIR/$tdir/d1
14032         test_mkdir -i0 -c1 $DIR/$tdir/d2
14033         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14034         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14035         cancel_lru_locks mdc
14036         cancel_lru_locks osc
14037         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14038         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14039         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14040         # XXX client can not do early lock cancel of OST lock
14041         # during rename (LU-4206), so cancel osc lock now.
14042         sleep 2
14043         cancel_lru_locks osc
14044         can1=$(do_facet mds1 \
14045                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14046                awk '/ldlm_cancel/ {print $2}')
14047         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14048                awk '/ldlm_bl_callback/ {print $2}')
14049         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14050         sleep 5
14051         can2=$(do_facet mds1 \
14052                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14053                awk '/ldlm_cancel/ {print $2}')
14054         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14055                awk '/ldlm_bl_callback/ {print $2}')
14056         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14057         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14058         lru_resize_enable mdc
14059         lru_resize_enable osc
14060 }
14061 run_test 120f "Early Lock Cancel: rename test"
14062
14063 test_120g() {
14064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14065         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14066                 skip_env "no early lock cancel on server"
14067         remote_mds_nodsh && skip "remote MDS with nodsh"
14068
14069         lru_resize_disable mdc
14070         lru_resize_disable osc
14071         count=10000
14072         echo create $count files
14073         test_mkdir $DIR/$tdir
14074         cancel_lru_locks mdc
14075         cancel_lru_locks osc
14076         t0=$(date +%s)
14077
14078         can0=$(do_facet $SINGLEMDS \
14079                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14080                awk '/ldlm_cancel/ {print $2}')
14081         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14082                awk '/ldlm_bl_callback/ {print $2}')
14083         createmany -o $DIR/$tdir/f $count
14084         sync
14085         can1=$(do_facet $SINGLEMDS \
14086                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14087                awk '/ldlm_cancel/ {print $2}')
14088         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14089                awk '/ldlm_bl_callback/ {print $2}')
14090         t1=$(date +%s)
14091         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14092         echo rm $count files
14093         rm -r $DIR/$tdir
14094         sync
14095         can2=$(do_facet $SINGLEMDS \
14096                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14097                awk '/ldlm_cancel/ {print $2}')
14098         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14099                awk '/ldlm_bl_callback/ {print $2}')
14100         t2=$(date +%s)
14101         echo total: $count removes in $((t2-t1))
14102         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14103         sleep 2
14104         # wait for commitment of removal
14105         lru_resize_enable mdc
14106         lru_resize_enable osc
14107 }
14108 run_test 120g "Early Lock Cancel: performance test"
14109
14110 test_121() { #bug #10589
14111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14112
14113         rm -rf $DIR/$tfile
14114         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14115 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14116         lctl set_param fail_loc=0x310
14117         cancel_lru_locks osc > /dev/null
14118         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14119         lctl set_param fail_loc=0
14120         [[ $reads -eq $writes ]] ||
14121                 error "read $reads blocks, must be $writes blocks"
14122 }
14123 run_test 121 "read cancel race ========="
14124
14125 test_123a_base() { # was test 123, statahead(bug 11401)
14126         local lsx="$1"
14127
14128         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14129
14130         SLOWOK=0
14131         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14132                 log "testing UP system. Performance may be lower than expected."
14133                 SLOWOK=1
14134         fi
14135         running_in_vm && SLOWOK=1
14136
14137         $LCTL set_param mdc.*.batch_stats=0
14138
14139         rm -rf $DIR/$tdir
14140         test_mkdir $DIR/$tdir
14141         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14142         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14143         MULT=10
14144         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14145                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14146
14147                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14148                 lctl set_param -n llite.*.statahead_max 0
14149                 lctl get_param llite.*.statahead_max
14150                 cancel_lru_locks mdc
14151                 cancel_lru_locks osc
14152                 stime=$(date +%s)
14153                 time $lsx $DIR/$tdir | wc -l
14154                 etime=$(date +%s)
14155                 delta=$((etime - stime))
14156                 log "$lsx $i files without statahead: $delta sec"
14157                 lctl set_param llite.*.statahead_max=$max
14158
14159                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14160                          awk '/statahead.wrong:/ { print $NF }')
14161                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14162                 cancel_lru_locks mdc
14163                 cancel_lru_locks osc
14164                 stime=$(date +%s)
14165                 time $lsx $DIR/$tdir | wc -l
14166                 etime=$(date +%s)
14167                 delta_sa=$((etime - stime))
14168                 log "$lsx $i files with statahead: $delta_sa sec"
14169                 lctl get_param -n llite.*.statahead_stats
14170                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14171                          awk '/statahead.wrong:/ { print $NF }')
14172
14173                 [[ $swrong -lt $ewrong ]] &&
14174                         log "statahead was stopped, maybe too many locks held!"
14175                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14176
14177                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14178                         max=$(lctl get_param -n llite.*.statahead_max |
14179                                 head -n 1)
14180                         lctl set_param -n llite.*.statahead_max 0
14181                         lctl get_param llite.*.statahead_max
14182                         cancel_lru_locks mdc
14183                         cancel_lru_locks osc
14184                         stime=$(date +%s)
14185                         time $lsx $DIR/$tdir | wc -l
14186                         etime=$(date +%s)
14187                         delta=$((etime - stime))
14188                         log "$lsx $i files again without statahead: $delta sec"
14189                         lctl set_param llite.*.statahead_max=$max
14190                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14191                                 if [ $SLOWOK -eq 0 ]; then
14192                                         error "$lsx $i files is slower with statahead!"
14193                                 else
14194                                         log "$lsx $i files is slower with statahead!"
14195                                 fi
14196                                 break
14197                         fi
14198                 fi
14199
14200                 [ $delta -gt 20 ] && break
14201                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14202                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14203         done
14204         log "$lsx done"
14205
14206         stime=$(date +%s)
14207         rm -r $DIR/$tdir
14208         sync
14209         etime=$(date +%s)
14210         delta=$((etime - stime))
14211         log "rm -r $DIR/$tdir/: $delta seconds"
14212         log "rm done"
14213         lctl get_param -n llite.*.statahead_stats
14214         $LCTL get_param mdc.*.batch_stats
14215 }
14216
14217 test_123aa() {
14218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14219
14220         test_123a_base "ls -l"
14221 }
14222 run_test 123aa "verify statahead work"
14223
14224 test_123ab() {
14225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14226
14227         statx_supported || skip_env "Test must be statx() syscall supported"
14228
14229         test_123a_base "$STATX -l"
14230 }
14231 run_test 123ab "verify statahead work by using statx"
14232
14233 test_123ac() {
14234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14235
14236         statx_supported || skip_env "Test must be statx() syscall supported"
14237
14238         local rpcs_before
14239         local rpcs_after
14240         local agl_before
14241         local agl_after
14242
14243         cancel_lru_locks $OSC
14244         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14245         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14246                      awk '/agl.total:/ { print $NF }')
14247         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14248         test_123a_base "$STATX --cached=always -D"
14249         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14250                     awk '/agl.total:/ { print $NF }')
14251         [ $agl_before -eq $agl_after ] ||
14252                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14253         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14254         [ $rpcs_after -eq $rpcs_before ] ||
14255                 error "$STATX should not send glimpse RPCs to $OSC"
14256 }
14257 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14258
14259 test_batch_statahead() {
14260         local max=$1
14261         local batch_max=$2
14262         local num=10000
14263         local batch_rpcs
14264         local unbatch_rpcs
14265         local hit_total
14266
14267         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14268         $LCTL set_param mdc.*.batch_stats=0
14269         $LCTL set_param llite.*.statahead_max=$max
14270         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14271         # Verify that batched statahead is faster than one without statahead
14272         test_123a_base "ls -l"
14273
14274         stack_trap "rm -rf $DIR/$tdir" EXIT
14275         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14276         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14277
14278         # unbatched statahead
14279         $LCTL set_param llite.*.statahead_batch_max=0
14280         $LCTL set_param llite.*.statahead_stats=clear
14281         $LCTL set_param mdc.*.stats=clear
14282         cancel_lru_locks mdc
14283         cancel_lru_locks osc
14284         time ls -l $DIR/$tdir | wc -l
14285         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14286         sleep 2
14287         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14288                     awk '/hit.total:/ { print $NF }')
14289         # hit ratio should be larger than 75% (7500).
14290         (( $hit_total > 7500 )) ||
14291                 error "unbatched statahead hit count ($hit_total) is too low"
14292
14293         # batched statahead
14294         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14295         $LCTL set_param llite.*.statahead_stats=clear
14296         $LCTL set_param mdc.*.batch_stats=clear
14297         $LCTL set_param mdc.*.stats=clear
14298         cancel_lru_locks mdc
14299         cancel_lru_locks osc
14300         time ls -l $DIR/$tdir | wc -l
14301         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14302         # wait for statahead thread to quit and update statahead stats
14303         sleep 2
14304         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14305                     awk '/hit.total:/ { print $NF }')
14306         # hit ratio should be larger than 75% (7500).
14307         (( $hit_total > 7500 )) ||
14308                 error "batched statahead hit count ($hit_total) is too low"
14309
14310         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14311         (( $unbatch_rpcs > $batch_rpcs )) ||
14312                 error "batched statahead does not reduce RPC count"
14313         $LCTL get_param mdc.*.batch_stats
14314 }
14315
14316 test_123ad() {
14317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14318
14319         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14320                 skip "Need server version at least 2.15.53"
14321
14322         local max
14323         local batch_max
14324
14325         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14326         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14327
14328         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14329         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14330
14331         test_batch_statahead 32 32
14332         test_batch_statahead 2048 256
14333 }
14334 run_test 123ad "Verify batching statahead works correctly"
14335
14336 test_123b () { # statahead(bug 15027)
14337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14338
14339         test_mkdir $DIR/$tdir
14340         createmany -o $DIR/$tdir/$tfile-%d 1000
14341
14342         cancel_lru_locks mdc
14343         cancel_lru_locks osc
14344
14345 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14346         lctl set_param fail_loc=0x80000803
14347         ls -lR $DIR/$tdir > /dev/null
14348         log "ls done"
14349         lctl set_param fail_loc=0x0
14350         lctl get_param -n llite.*.statahead_stats
14351         rm -r $DIR/$tdir
14352         sync
14353
14354 }
14355 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14356
14357 test_123c() {
14358         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14359
14360         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14361         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14362         touch $DIR/$tdir.1/{1..3}
14363         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14364
14365         remount_client $MOUNT
14366
14367         $MULTIOP $DIR/$tdir.0 Q
14368
14369         # let statahead to complete
14370         ls -l $DIR/$tdir.0 > /dev/null
14371
14372         testid=$(echo $TESTNAME | tr '_' ' ')
14373         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14374                 error "statahead warning" || true
14375 }
14376 run_test 123c "Can not initialize inode warning on DNE statahead"
14377
14378 test_123d() {
14379         local num=100
14380         local swrong
14381         local ewrong
14382
14383         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14384         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14385                 error "setdirstripe $DIR/$tdir failed"
14386         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14387         remount_client $MOUNT
14388         $LCTL get_param llite.*.statahead_max
14389         $LCTL set_param llite.*.statahead_stats=0 ||
14390                 error "clear statahead_stats failed"
14391         swrong=$(lctl get_param -n llite.*.statahead_stats |
14392                  awk '/statahead.wrong:/ { print $NF }')
14393         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14394         # wait for statahead thread finished to update hit/miss stats.
14395         sleep 1
14396         $LCTL get_param -n llite.*.statahead_stats
14397         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14398                  awk '/statahead.wrong:/ { print $NF }')
14399         (( $swrong == $ewrong )) ||
14400                 log "statahead was stopped, maybe too many locks held!"
14401 }
14402 run_test 123d "Statahead on striped directories works correctly"
14403
14404 test_123e() {
14405         local max
14406         local batch_max
14407         local dir=$DIR/$tdir
14408
14409         mkdir $dir || error "mkdir $dir failed"
14410         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14411         stack_trap "rm -rf $dir"
14412
14413         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14414
14415         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14416         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14417         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14418         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14419
14420         $LCTL set_param llite.*.statahead_max=2048
14421         $LCTL set_param llite.*.statahead_batch_max=1024
14422
14423         ls -l $dir
14424         $LCTL get_param mdc.*.batch_stats
14425         $LCTL get_param llite.*.statahead_*
14426 }
14427 run_test 123e "statahead with large wide striping"
14428
14429 test_123f() {
14430         local max
14431         local batch_max
14432         local dir=$DIR/$tdir
14433
14434         mkdir $dir || error "mkdir $dir failed"
14435         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14436         stack_trap "rm -rf $dir"
14437
14438         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14439
14440         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14441         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14442
14443         $LCTL set_param llite.*.statahead_max=64
14444         $LCTL set_param llite.*.statahead_batch_max=64
14445
14446         ls -l $dir
14447         lctl get_param mdc.*.batch_stats
14448         lctl get_param llite.*.statahead_*
14449
14450         $LCTL set_param llite.*.statahead_max=$max
14451         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14452 }
14453 run_test 123f "Retry mechanism with large wide striping files"
14454
14455 test_124a() {
14456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14457         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14458                 skip_env "no lru resize on server"
14459
14460         local NR=2000
14461
14462         test_mkdir $DIR/$tdir
14463
14464         log "create $NR files at $DIR/$tdir"
14465         createmany -o $DIR/$tdir/f $NR ||
14466                 error "failed to create $NR files in $DIR/$tdir"
14467
14468         cancel_lru_locks mdc
14469         ls -l $DIR/$tdir > /dev/null
14470
14471         local NSDIR=""
14472         local LRU_SIZE=0
14473         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14474                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14475                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14476                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14477                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14478                         log "NSDIR=$NSDIR"
14479                         log "NS=$(basename $NSDIR)"
14480                         break
14481                 fi
14482         done
14483
14484         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14485                 skip "Not enough cached locks created!"
14486         fi
14487         log "LRU=$LRU_SIZE"
14488
14489         local SLEEP=30
14490
14491         # We know that lru resize allows one client to hold $LIMIT locks
14492         # for 10h. After that locks begin to be killed by client.
14493         local MAX_HRS=10
14494         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14495         log "LIMIT=$LIMIT"
14496         if [ $LIMIT -lt $LRU_SIZE ]; then
14497                 skip "Limit is too small $LIMIT"
14498         fi
14499
14500         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14501         # killing locks. Some time was spent for creating locks. This means
14502         # that up to the moment of sleep finish we must have killed some of
14503         # them (10-100 locks). This depends on how fast ther were created.
14504         # Many of them were touched in almost the same moment and thus will
14505         # be killed in groups.
14506         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14507
14508         # Use $LRU_SIZE_B here to take into account real number of locks
14509         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14510         local LRU_SIZE_B=$LRU_SIZE
14511         log "LVF=$LVF"
14512         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14513         log "OLD_LVF=$OLD_LVF"
14514         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14515
14516         # Let's make sure that we really have some margin. Client checks
14517         # cached locks every 10 sec.
14518         SLEEP=$((SLEEP+20))
14519         log "Sleep ${SLEEP} sec"
14520         local SEC=0
14521         while ((SEC<$SLEEP)); do
14522                 echo -n "..."
14523                 sleep 5
14524                 SEC=$((SEC+5))
14525                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14526                 echo -n "$LRU_SIZE"
14527         done
14528         echo ""
14529         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14530         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14531
14532         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14533                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14534                 unlinkmany $DIR/$tdir/f $NR
14535                 return
14536         }
14537
14538         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14539         log "unlink $NR files at $DIR/$tdir"
14540         unlinkmany $DIR/$tdir/f $NR
14541 }
14542 run_test 124a "lru resize ======================================="
14543
14544 get_max_pool_limit()
14545 {
14546         local limit=$($LCTL get_param \
14547                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14548         local max=0
14549         for l in $limit; do
14550                 if [[ $l -gt $max ]]; then
14551                         max=$l
14552                 fi
14553         done
14554         echo $max
14555 }
14556
14557 test_124b() {
14558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14559         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14560                 skip_env "no lru resize on server"
14561
14562         LIMIT=$(get_max_pool_limit)
14563
14564         NR=$(($(default_lru_size)*20))
14565         if [[ $NR -gt $LIMIT ]]; then
14566                 log "Limit lock number by $LIMIT locks"
14567                 NR=$LIMIT
14568         fi
14569
14570         IFree=$(mdsrate_inodes_available)
14571         if [ $IFree -lt $NR ]; then
14572                 log "Limit lock number by $IFree inodes"
14573                 NR=$IFree
14574         fi
14575
14576         lru_resize_disable mdc
14577         test_mkdir -p $DIR/$tdir/disable_lru_resize
14578
14579         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14580         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14581         cancel_lru_locks mdc
14582         stime=`date +%s`
14583         PID=""
14584         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14585         PID="$PID $!"
14586         sleep 2
14587         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14588         PID="$PID $!"
14589         sleep 2
14590         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14591         PID="$PID $!"
14592         wait $PID
14593         etime=`date +%s`
14594         nolruresize_delta=$((etime-stime))
14595         log "ls -la time: $nolruresize_delta seconds"
14596         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14597         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14598
14599         lru_resize_enable mdc
14600         test_mkdir -p $DIR/$tdir/enable_lru_resize
14601
14602         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14603         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14604         cancel_lru_locks mdc
14605         stime=`date +%s`
14606         PID=""
14607         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14608         PID="$PID $!"
14609         sleep 2
14610         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14611         PID="$PID $!"
14612         sleep 2
14613         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14614         PID="$PID $!"
14615         wait $PID
14616         etime=`date +%s`
14617         lruresize_delta=$((etime-stime))
14618         log "ls -la time: $lruresize_delta seconds"
14619         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14620
14621         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14622                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14623         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14624                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14625         else
14626                 log "lru resize performs the same with no lru resize"
14627         fi
14628         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14629 }
14630 run_test 124b "lru resize (performance test) ======================="
14631
14632 test_124c() {
14633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14634         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14635                 skip_env "no lru resize on server"
14636
14637         # cache ununsed locks on client
14638         local nr=100
14639         cancel_lru_locks mdc
14640         test_mkdir $DIR/$tdir
14641         createmany -o $DIR/$tdir/f $nr ||
14642                 error "failed to create $nr files in $DIR/$tdir"
14643         ls -l $DIR/$tdir > /dev/null
14644
14645         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14646         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14647         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14648         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14649         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14650
14651         # set lru_max_age to 1 sec
14652         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14653         echo "sleep $((recalc_p * 2)) seconds..."
14654         sleep $((recalc_p * 2))
14655
14656         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14657         # restore lru_max_age
14658         $LCTL set_param -n $nsdir.lru_max_age $max_age
14659         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14660         unlinkmany $DIR/$tdir/f $nr
14661 }
14662 run_test 124c "LRUR cancel very aged locks"
14663
14664 test_124d() {
14665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14666         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14667                 skip_env "no lru resize on server"
14668
14669         # cache ununsed locks on client
14670         local nr=100
14671
14672         lru_resize_disable mdc
14673         stack_trap "lru_resize_enable mdc" EXIT
14674
14675         cancel_lru_locks mdc
14676
14677         # asynchronous object destroy at MDT could cause bl ast to client
14678         test_mkdir $DIR/$tdir
14679         createmany -o $DIR/$tdir/f $nr ||
14680                 error "failed to create $nr files in $DIR/$tdir"
14681         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14682
14683         ls -l $DIR/$tdir > /dev/null
14684
14685         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14686         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14687         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14688         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14689
14690         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14691
14692         # set lru_max_age to 1 sec
14693         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14694         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14695
14696         echo "sleep $((recalc_p * 2)) seconds..."
14697         sleep $((recalc_p * 2))
14698
14699         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14700
14701         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14702 }
14703 run_test 124d "cancel very aged locks if lru-resize disabled"
14704
14705 test_125() { # 13358
14706         $LCTL get_param -n llite.*.client_type | grep -q local ||
14707                 skip "must run as local client"
14708         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14709                 skip_env "must have acl enabled"
14710         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14711         id $USER0 || skip_env "missing user $USER0"
14712
14713         test_mkdir $DIR/$tdir
14714         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14715         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14716                 error "setfacl $DIR/$tdir failed"
14717         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14718 }
14719 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14720
14721 test_126() { # bug 12829/13455
14722         $GSS && skip_env "must run as gss disabled"
14723         $LCTL get_param -n llite.*.client_type | grep -q local ||
14724                 skip "must run as local client"
14725         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14726
14727         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14728         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14729         rm -f $DIR/$tfile
14730         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14731 }
14732 run_test 126 "check that the fsgid provided by the client is taken into account"
14733
14734 test_127a() { # bug 15521
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736         local name count samp unit min max sum sumsq
14737         local tmpfile=$TMP/$tfile.tmp
14738
14739         # enable stats header if it is disabled
14740         $LCTL set_param enable_stats_header=1
14741
14742         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14743         echo "stats before reset"
14744         stack_trap "rm -f $tmpfile"
14745         local now=$(date +%s)
14746
14747         $LCTL get_param osc.*.stats | tee $tmpfile
14748
14749         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14750         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14751         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14752         local uptime=$(awk '{ print $1 }' /proc/uptime)
14753
14754         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14755         (( ${snapshot_time%\.*} >= $now - 5 &&
14756            ${snapshot_time%\.*} <= $now + 5 )) ||
14757                 error "snapshot_time=$snapshot_time != now=$now"
14758         # elapsed _should_ be from mount, but at least less than uptime
14759         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14760                 error "elapsed=$elapsed > uptime=$uptime"
14761         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14762            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14763                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14764
14765         $LCTL set_param osc.*.stats=0
14766         local reset=$(date +%s)
14767         local fsize=$((2048 * 1024))
14768
14769         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14770         cancel_lru_locks osc
14771         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14772
14773         now=$(date +%s)
14774         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14775         while read name count samp unit min max sum sumsq; do
14776                 [[ "$samp" == "samples" ]] || continue
14777
14778                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14779                 [ ! $min ] && error "Missing min value for $name proc entry"
14780                 eval $name=$count || error "Wrong proc format"
14781
14782                 case $name in
14783                 read_bytes|write_bytes)
14784                         [[ "$unit" =~ "bytes" ]] ||
14785                                 error "unit is not 'bytes': $unit"
14786                         (( $min >= 4096 )) || error "min is too small: $min"
14787                         (( $min <= $fsize )) || error "min is too big: $min"
14788                         (( $max >= 4096 )) || error "max is too small: $max"
14789                         (( $max <= $fsize )) || error "max is too big: $max"
14790                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14791                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14792                                 error "sumsquare is too small: $sumsq"
14793                         (( $sumsq <= $fsize * $fsize )) ||
14794                                 error "sumsquare is too big: $sumsq"
14795                         ;;
14796                 ost_read|ost_write)
14797                         [[ "$unit" =~ "usec" ]] ||
14798                                 error "unit is not 'usec': $unit"
14799                         ;;
14800                 *)      ;;
14801                 esac
14802         done < $tmpfile
14803
14804         #check that we actually got some stats
14805         [ "$read_bytes" ] || error "Missing read_bytes stats"
14806         [ "$write_bytes" ] || error "Missing write_bytes stats"
14807         [ "$read_bytes" != 0 ] || error "no read done"
14808         [ "$write_bytes" != 0 ] || error "no write done"
14809
14810         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14811         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14812         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14813
14814         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14815         (( ${snapshot_time%\.*} >= $now - 5 &&
14816            ${snapshot_time%\.*} <= $now + 5 )) ||
14817                 error "reset snapshot_time=$snapshot_time != now=$now"
14818         # elapsed should be from time of stats reset
14819         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14820            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14821                 error "reset elapsed=$elapsed > $now - $reset"
14822         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14823            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14824                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14825 }
14826 run_test 127a "verify the client stats are sane"
14827
14828 test_127b() { # bug LU-333
14829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14830         local name count samp unit min max sum sumsq
14831
14832         echo "stats before reset"
14833         $LCTL get_param llite.*.stats
14834         $LCTL set_param llite.*.stats=0
14835
14836         # perform 2 reads and writes so MAX is different from SUM.
14837         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14838         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14839         cancel_lru_locks osc
14840         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14841         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14842
14843         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14844         stack_trap "rm -f $TMP/$tfile.tmp"
14845         while read name count samp unit min max sum sumsq; do
14846                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14847                 eval $name=$count || error "Wrong proc format"
14848
14849                 case $name in
14850                 read_bytes|write_bytes)
14851                         [[ "$unit" =~ "bytes" ]] ||
14852                                 error "unit is not 'bytes': $unit"
14853                         (( $count == 2 )) || error "count is not 2: $count"
14854                         (( $min == $PAGE_SIZE )) ||
14855                                 error "min is not $PAGE_SIZE: $min"
14856                         (( $max == $PAGE_SIZE )) ||
14857                                 error "max is not $PAGE_SIZE: $max"
14858                         (( $sum == $PAGE_SIZE * 2 )) ||
14859                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14860                         ;;
14861                 read|write)
14862                         [[ "$unit" =~ "usec" ]] ||
14863                                 error "unit is not 'usec': $unit"
14864                         ;;
14865                 *)      ;;
14866                 esac
14867         done < $TMP/$tfile.tmp
14868
14869         #check that we actually got some stats
14870         [ "$read_bytes" ] || error "Missing read_bytes stats"
14871         [ "$write_bytes" ] || error "Missing write_bytes stats"
14872         [ "$read_bytes" != 0 ] || error "no read done"
14873         [ "$write_bytes" != 0 ] || error "no write done"
14874 }
14875 run_test 127b "verify the llite client stats are sane"
14876
14877 test_127c() { # LU-12394
14878         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14879         local size
14880         local bsize
14881         local reads
14882         local writes
14883         local count
14884
14885         $LCTL set_param llite.*.extents_stats=1
14886         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14887
14888         # Use two stripes so there is enough space in default config
14889         $LFS setstripe -c 2 $DIR/$tfile
14890
14891         # Extent stats start at 0-4K and go in power of two buckets
14892         # LL_HIST_START = 12 --> 2^12 = 4K
14893         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14894         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14895         # small configs
14896         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14897                 do
14898                 # Write and read, 2x each, second time at a non-zero offset
14899                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14900                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14901                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14902                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14903                 rm -f $DIR/$tfile
14904         done
14905
14906         $LCTL get_param llite.*.extents_stats
14907
14908         count=2
14909         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14910                 do
14911                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14912                                 grep -m 1 $bsize)
14913                 reads=$(echo $bucket | awk '{print $5}')
14914                 writes=$(echo $bucket | awk '{print $9}')
14915                 [ "$reads" -eq $count ] ||
14916                         error "$reads reads in < $bsize bucket, expect $count"
14917                 [ "$writes" -eq $count ] ||
14918                         error "$writes writes in < $bsize bucket, expect $count"
14919         done
14920
14921         # Test mmap write and read
14922         $LCTL set_param llite.*.extents_stats=c
14923         size=512
14924         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14925         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14926         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14927
14928         $LCTL get_param llite.*.extents_stats
14929
14930         count=$(((size*1024) / PAGE_SIZE))
14931
14932         bsize=$((2 * PAGE_SIZE / 1024))K
14933
14934         bucket=$($LCTL get_param -n llite.*.extents_stats |
14935                         grep -m 1 $bsize)
14936         reads=$(echo $bucket | awk '{print $5}')
14937         writes=$(echo $bucket | awk '{print $9}')
14938         # mmap writes fault in the page first, creating an additonal read
14939         [ "$reads" -eq $((2 * count)) ] ||
14940                 error "$reads reads in < $bsize bucket, expect $count"
14941         [ "$writes" -eq $count ] ||
14942                 error "$writes writes in < $bsize bucket, expect $count"
14943 }
14944 run_test 127c "test llite extent stats with regular & mmap i/o"
14945
14946 test_128() { # bug 15212
14947         touch $DIR/$tfile
14948         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14949                 find $DIR/$tfile
14950                 find $DIR/$tfile
14951         EOF
14952
14953         result=$(grep error $TMP/$tfile.log)
14954         rm -f $DIR/$tfile $TMP/$tfile.log
14955         [ -z "$result" ] ||
14956                 error "consecutive find's under interactive lfs failed"
14957 }
14958 run_test 128 "interactive lfs for 2 consecutive find's"
14959
14960 set_dir_limits () {
14961         local mntdev
14962         local canondev
14963         local node
14964
14965         local ldproc=/proc/fs/ldiskfs
14966         local facets=$(get_facets MDS)
14967
14968         for facet in ${facets//,/ }; do
14969                 canondev=$(ldiskfs_canon \
14970                            *.$(convert_facet2label $facet).mntdev $facet)
14971                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14972                         ldproc=/sys/fs/ldiskfs
14973                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14974                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14975         done
14976 }
14977
14978 check_mds_dmesg() {
14979         local facets=$(get_facets MDS)
14980         for facet in ${facets//,/ }; do
14981                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14982         done
14983         return 1
14984 }
14985
14986 test_129() {
14987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14988         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14989                 skip "Need MDS version with at least 2.5.56"
14990         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14991                 skip_env "ldiskfs only test"
14992         fi
14993         remote_mds_nodsh && skip "remote MDS with nodsh"
14994
14995         local ENOSPC=28
14996         local has_warning=false
14997
14998         rm -rf $DIR/$tdir
14999         mkdir -p $DIR/$tdir
15000
15001         # block size of mds1
15002         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15003         set_dir_limits $maxsize $((maxsize * 6 / 8))
15004         stack_trap "set_dir_limits 0 0"
15005         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15006         local dirsize=$(stat -c%s "$DIR/$tdir")
15007         local nfiles=0
15008         while (( $dirsize <= $maxsize )); do
15009                 $MCREATE $DIR/$tdir/file_base_$nfiles
15010                 rc=$?
15011                 # check two errors:
15012                 # ENOSPC for ext4 max_dir_size, which has been used since
15013                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15014                 if (( rc == ENOSPC )); then
15015                         set_dir_limits 0 0
15016                         echo "rc=$rc returned as expected after $nfiles files"
15017
15018                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15019                                 error "create failed w/o dir size limit"
15020
15021                         # messages may be rate limited if test is run repeatedly
15022                         check_mds_dmesg '"is approaching max"' ||
15023                                 echo "warning message should be output"
15024                         check_mds_dmesg '"has reached max"' ||
15025                                 echo "reached message should be output"
15026
15027                         dirsize=$(stat -c%s "$DIR/$tdir")
15028
15029                         [[ $dirsize -ge $maxsize ]] && return 0
15030                         error "dirsize $dirsize < $maxsize after $nfiles files"
15031                 elif (( rc != 0 )); then
15032                         break
15033                 fi
15034                 nfiles=$((nfiles + 1))
15035                 dirsize=$(stat -c%s "$DIR/$tdir")
15036         done
15037
15038         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15039 }
15040 run_test 129 "test directory size limit ========================"
15041
15042 OLDIFS="$IFS"
15043 cleanup_130() {
15044         trap 0
15045         IFS="$OLDIFS"
15046         rm -f $DIR/$tfile
15047 }
15048
15049 test_130a() {
15050         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15051         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15052
15053         trap cleanup_130 EXIT RETURN
15054
15055         local fm_file=$DIR/$tfile
15056         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15057         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15058                 error "dd failed for $fm_file"
15059
15060         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15061         filefrag -ves $fm_file
15062         local rc=$?
15063         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15064                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15065         (( $rc == 0 )) || error "filefrag $fm_file failed"
15066
15067         filefrag_op=$(filefrag -ve -k $fm_file |
15068                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15069         local lun=$($LFS getstripe -i $fm_file)
15070
15071         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15072         IFS=$'\n'
15073         local tot_len=0
15074         for line in $filefrag_op; do
15075                 local frag_lun=$(echo $line | cut -d: -f5)
15076                 local ext_len=$(echo $line | cut -d: -f4)
15077
15078                 if (( $frag_lun != $lun )); then
15079                         error "FIEMAP on 1-stripe file($fm_file) failed"
15080                         return
15081                 fi
15082                 (( tot_len += ext_len ))
15083         done
15084
15085         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15086                 error "FIEMAP on 1-stripe file($fm_file) failed"
15087                 return
15088         fi
15089
15090         echo "FIEMAP on single striped file succeeded"
15091 }
15092 run_test 130a "FIEMAP (1-stripe file)"
15093
15094 test_130b() {
15095         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15096
15097         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15098         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15099         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15100                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15101
15102         trap cleanup_130 EXIT RETURN
15103
15104         local fm_file=$DIR/$tfile
15105         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15106                 error "setstripe on $fm_file"
15107
15108         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15109                 error "dd failed on $fm_file"
15110
15111         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15112         filefrag_op=$(filefrag -ve -k $fm_file |
15113                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15114
15115         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15116                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15117
15118         IFS=$'\n'
15119         local tot_len=0
15120         local num_luns=1
15121
15122         for line in $filefrag_op; do
15123                 local frag_lun=$(echo $line | cut -d: -f5 |
15124                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15125                 local ext_len=$(echo $line | cut -d: -f4)
15126                 if (( $frag_lun != $last_lun )); then
15127                         if (( tot_len != 1024 )); then
15128                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15129                                 return
15130                         else
15131                                 (( num_luns += 1 ))
15132                                 tot_len=0
15133                         fi
15134                 fi
15135                 (( tot_len += ext_len ))
15136                 last_lun=$frag_lun
15137         done
15138         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15139                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15140                 return
15141         fi
15142
15143         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15144 }
15145 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15146
15147 test_130c() {
15148         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15149
15150         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15151         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15152         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15153                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15154
15155         trap cleanup_130 EXIT RETURN
15156
15157         local fm_file=$DIR/$tfile
15158         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15159
15160         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15161                 error "dd failed on $fm_file"
15162
15163         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15164         filefrag_op=$(filefrag -ve -k $fm_file |
15165                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15166
15167         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15168                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15169
15170         IFS=$'\n'
15171         local tot_len=0
15172         local num_luns=1
15173         for line in $filefrag_op; do
15174                 local frag_lun=$(echo $line | cut -d: -f5 |
15175                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15176                 local ext_len=$(echo $line | cut -d: -f4)
15177                 if (( $frag_lun != $last_lun )); then
15178                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15179                         if (( logical != 512 )); then
15180                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15181                                 return
15182                         fi
15183                         if (( tot_len != 512 )); then
15184                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15185                                 return
15186                         else
15187                                 (( num_luns += 1 ))
15188                                 tot_len=0
15189                         fi
15190                 fi
15191                 (( tot_len += ext_len ))
15192                 last_lun=$frag_lun
15193         done
15194         if (( num_luns != 2 || tot_len != 512 )); then
15195                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15196                 return
15197         fi
15198
15199         echo "FIEMAP on 2-stripe file with hole succeeded"
15200 }
15201 run_test 130c "FIEMAP (2-stripe file with hole)"
15202
15203 test_130d() {
15204         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15205
15206         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15207         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15208         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15209                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15210
15211         trap cleanup_130 EXIT RETURN
15212
15213         local fm_file=$DIR/$tfile
15214         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15215                         error "setstripe on $fm_file"
15216
15217         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15218         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15219                 error "dd failed on $fm_file"
15220
15221         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15222         filefrag_op=$(filefrag -ve -k $fm_file |
15223                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15224
15225         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15226                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15227
15228         IFS=$'\n'
15229         local tot_len=0
15230         local num_luns=1
15231         for line in $filefrag_op; do
15232                 local frag_lun=$(echo $line | cut -d: -f5 |
15233                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15234                 local ext_len=$(echo $line | cut -d: -f4)
15235                 if (( $frag_lun != $last_lun )); then
15236                         if (( tot_len != 1024 )); then
15237                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15238                                 return
15239                         else
15240                                 (( num_luns += 1 ))
15241                                 local tot_len=0
15242                         fi
15243                 fi
15244                 (( tot_len += ext_len ))
15245                 last_lun=$frag_lun
15246         done
15247         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15248                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15249                 return
15250         fi
15251
15252         echo "FIEMAP on N-stripe file succeeded"
15253 }
15254 run_test 130d "FIEMAP (N-stripe file)"
15255
15256 test_130e() {
15257         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15258
15259         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15260         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15261         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15262                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15263
15264         trap cleanup_130 EXIT RETURN
15265
15266         local fm_file=$DIR/$tfile
15267         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15268         stack_trap "rm -f $fm_file"
15269
15270         local num_blks=512
15271         local expected_len=$(( (num_blks / 2) * 64 ))
15272         for ((i = 0; i < $num_blks; i++)); do
15273                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15274                         conv=notrunc > /dev/null 2>&1
15275         done
15276
15277         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15278         filefrag_op=$(filefrag -ve -k $fm_file |
15279                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15280
15281         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15282
15283         IFS=$'\n'
15284         local tot_len=0
15285         local num_luns=1
15286         for line in $filefrag_op; do
15287                 local frag_lun=$(echo $line | cut -d: -f5)
15288                 local ext_len=$(echo $line | cut -d: -f4)
15289                 if (( $frag_lun != $last_lun )); then
15290                         if (( tot_len != $expected_len )); then
15291                                 error "OST$last_lun $tot_len != $expected_len"
15292                         else
15293                                 (( num_luns += 1 ))
15294                                 tot_len=0
15295                         fi
15296                 fi
15297                 (( tot_len += ext_len ))
15298                 last_lun=$frag_lun
15299         done
15300         if (( num_luns != 2 || tot_len != $expected_len )); then
15301                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15302         fi
15303
15304         echo "FIEMAP with continuation calls succeeded"
15305 }
15306 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15307
15308 test_130f() {
15309         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15310         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15311         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15312                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15313
15314         local fm_file=$DIR/$tfile
15315         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15316                 error "multiop create with lov_delay_create on $fm_file"
15317
15318         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15319         filefrag_extents=$(filefrag -vek $fm_file |
15320                            awk '/extents? found/ { print $2 }')
15321         if (( $filefrag_extents != 0 )); then
15322                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15323         fi
15324
15325         rm -f $fm_file
15326 }
15327 run_test 130f "FIEMAP (unstriped file)"
15328
15329 test_130g() {
15330         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15331                 skip "Need MDS version with at least 2.12.53 for overstriping"
15332         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15333         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15334         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15335                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15336
15337         local file=$DIR/$tfile
15338         local nr=$((OSTCOUNT * 100))
15339
15340         $LFS setstripe -C $nr -S1M $file ||
15341                 error "failed to setstripe -C $nr $file"
15342
15343         stack_trap "rm -f $file"
15344         dd if=/dev/zero of=$file count=$nr bs=1M
15345         sync
15346         nr=$($LFS getstripe -c $file)
15347
15348         local extents=$(filefrag -v $file |
15349                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15350
15351         echo "filefrag list $extents extents in file with stripecount $nr"
15352         if (( extents < nr )); then
15353                 $LFS getstripe $file
15354                 filefrag -v $file
15355                 error "filefrag printed $extents < $nr extents"
15356         fi
15357 }
15358 run_test 130g "FIEMAP (overstripe file)"
15359
15360 # Test for writev/readv
15361 test_131a() {
15362         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15363                 error "writev test failed"
15364         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15365                 error "readv failed"
15366         rm -f $DIR/$tfile
15367 }
15368 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15369
15370 test_131b() {
15371         local fsize=$((524288 + 1048576 + 1572864))
15372         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15373                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15374                         error "append writev test failed"
15375
15376         ((fsize += 1572864 + 1048576))
15377         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15378                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15379                         error "append writev test failed"
15380         rm -f $DIR/$tfile
15381 }
15382 run_test 131b "test append writev"
15383
15384 test_131c() {
15385         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15386         error "NOT PASS"
15387 }
15388 run_test 131c "test read/write on file w/o objects"
15389
15390 test_131d() {
15391         rwv -f $DIR/$tfile -w -n 1 1572864
15392         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15393         if [ "$NOB" != 1572864 ]; then
15394                 error "Short read filed: read $NOB bytes instead of 1572864"
15395         fi
15396         rm -f $DIR/$tfile
15397 }
15398 run_test 131d "test short read"
15399
15400 test_131e() {
15401         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15402         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15403         error "read hitting hole failed"
15404         rm -f $DIR/$tfile
15405 }
15406 run_test 131e "test read hitting hole"
15407
15408 check_stats() {
15409         local facet=$1
15410         local op=$2
15411         local want=${3:-0}
15412         local res
15413
15414         # open             11 samples [usecs] 468 4793 13658 35791898
15415         case $facet in
15416         mds*) res=($(do_facet $facet \
15417                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15418                  ;;
15419         ost*) res=($(do_facet $facet \
15420                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15421                  ;;
15422         *) error "Wrong facet '$facet'" ;;
15423         esac
15424         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15425         # if $want is zero, it means any stat increment is ok.
15426         if (( $want > 0 )); then
15427                 local count=${res[1]}
15428
15429                 if (( $count != $want )); then
15430                         if [[ $facet =~ "mds" ]]; then
15431                                 do_nodes $(comma_list $(mdts_nodes)) \
15432                                         $LCTL get_param mdt.*.md_stats
15433                         else
15434                                 do_nodes $(comma_list $(osts-nodes)) \
15435                                         $LCTL get_param obdfilter.*.stats
15436                         fi
15437                         error "The $op counter on $facet is $count, not $want"
15438                 fi
15439         fi
15440 }
15441
15442 test_133a() {
15443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15444         remote_ost_nodsh && skip "remote OST with nodsh"
15445         remote_mds_nodsh && skip "remote MDS with nodsh"
15446         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15447                 skip_env "MDS doesn't support rename stats"
15448
15449         local testdir=$DIR/${tdir}/stats_testdir
15450
15451         mkdir -p $DIR/${tdir}
15452
15453         # clear stats.
15454         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15455         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15456
15457         # verify mdt stats first.
15458         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15459         check_stats $SINGLEMDS "mkdir" 1
15460
15461         # clear "open" from "lfs mkdir" above
15462         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15463         touch ${testdir}/${tfile} || error "touch failed"
15464         check_stats $SINGLEMDS "open" 1
15465         check_stats $SINGLEMDS "close" 1
15466         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15467                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15468                 check_stats $SINGLEMDS "mknod" 2
15469         }
15470         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15471         check_stats $SINGLEMDS "unlink" 1
15472         rm -f ${testdir}/${tfile} || error "file remove failed"
15473         check_stats $SINGLEMDS "unlink" 2
15474
15475         # remove working dir and check mdt stats again.
15476         rmdir ${testdir} || error "rmdir failed"
15477         check_stats $SINGLEMDS "rmdir" 1
15478
15479         local testdir1=$DIR/${tdir}/stats_testdir1
15480         mkdir_on_mdt0 -p ${testdir}
15481         mkdir_on_mdt0 -p ${testdir1}
15482         touch ${testdir1}/test1
15483         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15484         check_stats $SINGLEMDS "crossdir_rename" 1
15485
15486         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15487         check_stats $SINGLEMDS "samedir_rename" 1
15488
15489         rm -rf $DIR/${tdir}
15490 }
15491 run_test 133a "Verifying MDT stats ========================================"
15492
15493 test_133b() {
15494         local res
15495
15496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15497         remote_ost_nodsh && skip "remote OST with nodsh"
15498         remote_mds_nodsh && skip "remote MDS with nodsh"
15499
15500         local testdir=$DIR/${tdir}/stats_testdir
15501
15502         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15503         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15504         touch ${testdir}/${tfile} || error "touch failed"
15505         cancel_lru_locks mdc
15506
15507         # clear stats.
15508         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15509         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15510
15511         # extra mdt stats verification.
15512         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15513         check_stats $SINGLEMDS "setattr" 1
15514         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15515         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15516         then            # LU-1740
15517                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15518                 check_stats $SINGLEMDS "getattr" 1
15519         fi
15520         rm -rf $DIR/${tdir}
15521
15522         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15523         # so the check below is not reliable
15524         [ $MDSCOUNT -eq 1 ] || return 0
15525
15526         # Sleep to avoid a cached response.
15527         #define OBD_STATFS_CACHE_SECONDS 1
15528         sleep 2
15529         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15530         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15531         $LFS df || error "lfs failed"
15532         check_stats $SINGLEMDS "statfs" 1
15533
15534         # check aggregated statfs (LU-10018)
15535         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15536                 return 0
15537         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15538                 return 0
15539         sleep 2
15540         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15541         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15542         df $DIR
15543         check_stats $SINGLEMDS "statfs" 1
15544
15545         # We want to check that the client didn't send OST_STATFS to
15546         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15547         # extra care is needed here.
15548         if remote_mds; then
15549                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15550                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15551
15552                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15553                 [ "$res" ] && error "OST got STATFS"
15554         fi
15555
15556         return 0
15557 }
15558 run_test 133b "Verifying extra MDT stats =================================="
15559
15560 test_133c() {
15561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15562         remote_ost_nodsh && skip "remote OST with nodsh"
15563         remote_mds_nodsh && skip "remote MDS with nodsh"
15564
15565         local testdir=$DIR/$tdir/stats_testdir
15566
15567         test_mkdir -p $testdir
15568
15569         # verify obdfilter stats.
15570         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15571         sync
15572         cancel_lru_locks osc
15573         wait_delete_completed
15574
15575         # clear stats.
15576         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15577         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15578
15579         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15580                 error "dd failed"
15581         sync
15582         cancel_lru_locks osc
15583         check_stats ost1 "write" 1
15584
15585         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15586         check_stats ost1 "read" 1
15587
15588         > $testdir/$tfile || error "truncate failed"
15589         check_stats ost1 "punch" 1
15590
15591         rm -f $testdir/$tfile || error "file remove failed"
15592         wait_delete_completed
15593         check_stats ost1 "destroy" 1
15594
15595         rm -rf $DIR/$tdir
15596 }
15597 run_test 133c "Verifying OST stats ========================================"
15598
15599 order_2() {
15600         local value=$1
15601         local orig=$value
15602         local order=1
15603
15604         while [ $value -ge 2 ]; do
15605                 order=$((order*2))
15606                 value=$((value/2))
15607         done
15608
15609         if [ $orig -gt $order ]; then
15610                 order=$((order*2))
15611         fi
15612         echo $order
15613 }
15614
15615 size_in_KMGT() {
15616     local value=$1
15617     local size=('K' 'M' 'G' 'T');
15618     local i=0
15619     local size_string=$value
15620
15621     while [ $value -ge 1024 ]; do
15622         if [ $i -gt 3 ]; then
15623             #T is the biggest unit we get here, if that is bigger,
15624             #just return XXXT
15625             size_string=${value}T
15626             break
15627         fi
15628         value=$((value >> 10))
15629         if [ $value -lt 1024 ]; then
15630             size_string=${value}${size[$i]}
15631             break
15632         fi
15633         i=$((i + 1))
15634     done
15635
15636     echo $size_string
15637 }
15638
15639 get_rename_size() {
15640         local size=$1
15641         local context=${2:-.}
15642         local sample=$(do_facet $SINGLEMDS $LCTL \
15643                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15644                 grep -A1 $context |
15645                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15646         echo $sample
15647 }
15648
15649 test_133d() {
15650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15651         remote_ost_nodsh && skip "remote OST with nodsh"
15652         remote_mds_nodsh && skip "remote MDS with nodsh"
15653         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15654                 skip_env "MDS doesn't support rename stats"
15655
15656         local testdir1=$DIR/${tdir}/stats_testdir1
15657         local testdir2=$DIR/${tdir}/stats_testdir2
15658         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15659
15660         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15661
15662         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15663         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15664
15665         createmany -o $testdir1/test 512 || error "createmany failed"
15666
15667         # check samedir rename size
15668         mv ${testdir1}/test0 ${testdir1}/test_0
15669
15670         local testdir1_size=$(ls -l $DIR/${tdir} |
15671                 awk '/stats_testdir1/ {print $5}')
15672         local testdir2_size=$(ls -l $DIR/${tdir} |
15673                 awk '/stats_testdir2/ {print $5}')
15674
15675         testdir1_size=$(order_2 $testdir1_size)
15676         testdir2_size=$(order_2 $testdir2_size)
15677
15678         testdir1_size=$(size_in_KMGT $testdir1_size)
15679         testdir2_size=$(size_in_KMGT $testdir2_size)
15680
15681         echo "source rename dir size: ${testdir1_size}"
15682         echo "target rename dir size: ${testdir2_size}"
15683
15684         local cmd="do_facet $SINGLEMDS $LCTL "
15685         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15686
15687         eval $cmd || error "$cmd failed"
15688         local samedir=$($cmd | grep 'same_dir')
15689         local same_sample=$(get_rename_size $testdir1_size)
15690         [ -z "$samedir" ] && error "samedir_rename_size count error"
15691         [[ $same_sample -eq 1 ]] ||
15692                 error "samedir_rename_size error $same_sample"
15693         echo "Check same dir rename stats success"
15694
15695         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15696
15697         # check crossdir rename size
15698         mv ${testdir1}/test_0 ${testdir2}/test_0
15699
15700         testdir1_size=$(ls -l $DIR/${tdir} |
15701                 awk '/stats_testdir1/ {print $5}')
15702         testdir2_size=$(ls -l $DIR/${tdir} |
15703                 awk '/stats_testdir2/ {print $5}')
15704
15705         testdir1_size=$(order_2 $testdir1_size)
15706         testdir2_size=$(order_2 $testdir2_size)
15707
15708         testdir1_size=$(size_in_KMGT $testdir1_size)
15709         testdir2_size=$(size_in_KMGT $testdir2_size)
15710
15711         echo "source rename dir size: ${testdir1_size}"
15712         echo "target rename dir size: ${testdir2_size}"
15713
15714         eval $cmd || error "$cmd failed"
15715         local crossdir=$($cmd | grep 'crossdir')
15716         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15717         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15718         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15719         [[ $src_sample -eq 1 ]] ||
15720                 error "crossdir_rename_size error $src_sample"
15721         [[ $tgt_sample -eq 1 ]] ||
15722                 error "crossdir_rename_size error $tgt_sample"
15723         echo "Check cross dir rename stats success"
15724         rm -rf $DIR/${tdir}
15725 }
15726 run_test 133d "Verifying rename_stats ========================================"
15727
15728 test_133e() {
15729         remote_mds_nodsh && skip "remote MDS with nodsh"
15730         remote_ost_nodsh && skip "remote OST with nodsh"
15731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15732
15733         local testdir=$DIR/${tdir}/stats_testdir
15734         local ctr f0 f1 bs=32768 count=42 sum
15735
15736         mkdir -p ${testdir} || error "mkdir failed"
15737
15738         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15739
15740         for ctr in {write,read}_bytes; do
15741                 sync
15742                 cancel_lru_locks osc
15743
15744                 do_facet ost1 $LCTL set_param -n \
15745                         "obdfilter.*.exports.clear=clear"
15746
15747                 if [ $ctr = write_bytes ]; then
15748                         f0=/dev/zero
15749                         f1=${testdir}/${tfile}
15750                 else
15751                         f0=${testdir}/${tfile}
15752                         f1=/dev/null
15753                 fi
15754
15755                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15756                         error "dd failed"
15757                 sync
15758                 cancel_lru_locks osc
15759
15760                 sum=$(do_facet ost1 $LCTL get_param \
15761                         "obdfilter.*.exports.*.stats" |
15762                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15763                                 $1 == ctr { sum += $7 }
15764                                 END { printf("%0.0f", sum) }')
15765
15766                 if ((sum != bs * count)); then
15767                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15768                 fi
15769         done
15770
15771         rm -rf $DIR/${tdir}
15772 }
15773 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15774
15775 test_133f() {
15776         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15777                 skip "too old lustre for get_param -R ($facet_ver)"
15778
15779         # verifying readability.
15780         $LCTL get_param -R '*' &> /dev/null
15781
15782         # Verifing writability with badarea_io.
15783         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15784         local skipped_params='force_lbug|changelog_mask|daemon_file'
15785         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15786                 egrep -v "$skipped_params" |
15787                 xargs -n 1 find $proc_dirs -name |
15788                 xargs -n 1 badarea_io ||
15789                 error "client badarea_io failed"
15790
15791         # remount the FS in case writes/reads /proc break the FS
15792         cleanup || error "failed to unmount"
15793         setup || error "failed to setup"
15794 }
15795 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15796
15797 test_133g() {
15798         remote_mds_nodsh && skip "remote MDS with nodsh"
15799         remote_ost_nodsh && skip "remote OST with nodsh"
15800
15801         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15802         local proc_dirs_str=$(eval echo $proc_dirs)
15803         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15804         local facet
15805         for facet in mds1 ost1; do
15806                 local facet_ver=$(lustre_version_code $facet)
15807                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15808                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15809                 else
15810                         log "$facet: too old lustre for get_param -R"
15811                 fi
15812                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15813                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15814                                 tr -d = | egrep -v $skipped_params |
15815                                 xargs -n 1 find $proc_dirs_str -name |
15816                                 xargs -n 1 badarea_io" ||
15817                                         error "$facet badarea_io failed"
15818                 else
15819                         skip_noexit "$facet: too old lustre for get_param -R"
15820                 fi
15821         done
15822
15823         # remount the FS in case writes/reads /proc break the FS
15824         cleanup || error "failed to unmount"
15825         setup || error "failed to setup"
15826 }
15827 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15828
15829 test_133h() {
15830         remote_mds_nodsh && skip "remote MDS with nodsh"
15831         remote_ost_nodsh && skip "remote OST with nodsh"
15832         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15833                 skip "Need MDS version at least 2.9.54"
15834
15835         local facet
15836         for facet in client mds1 ost1; do
15837                 # Get the list of files that are missing the terminating newline
15838                 local plist=$(do_facet $facet
15839                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15840                 local ent
15841                 for ent in $plist; do
15842                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15843                                 awk -v FS='\v' -v RS='\v\v' \
15844                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15845                                         print FILENAME}'" 2>/dev/null)
15846                         [ -z $missing ] || {
15847                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15848                                 error "file does not end with newline: $facet-$ent"
15849                         }
15850                 done
15851         done
15852 }
15853 run_test 133h "Proc files should end with newlines"
15854
15855 test_134a() {
15856         remote_mds_nodsh && skip "remote MDS with nodsh"
15857         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15858                 skip "Need MDS version at least 2.7.54"
15859
15860         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15861         cancel_lru_locks mdc
15862
15863         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15864         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15865         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15866
15867         local nr=1000
15868         createmany -o $DIR/$tdir/f $nr ||
15869                 error "failed to create $nr files in $DIR/$tdir"
15870         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15871
15872         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15873         do_facet mds1 $LCTL set_param fail_loc=0x327
15874         do_facet mds1 $LCTL set_param fail_val=500
15875         touch $DIR/$tdir/m
15876
15877         echo "sleep 10 seconds ..."
15878         sleep 10
15879         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15880
15881         do_facet mds1 $LCTL set_param fail_loc=0
15882         do_facet mds1 $LCTL set_param fail_val=0
15883         [ $lck_cnt -lt $unused ] ||
15884                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15885
15886         rm $DIR/$tdir/m
15887         unlinkmany $DIR/$tdir/f $nr
15888 }
15889 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15890
15891 test_134b() {
15892         remote_mds_nodsh && skip "remote MDS with nodsh"
15893         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15894                 skip "Need MDS version at least 2.7.54"
15895
15896         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15897         cancel_lru_locks mdc
15898
15899         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15900                         ldlm.lock_reclaim_threshold_mb)
15901         # disable reclaim temporarily
15902         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15903
15904         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15905         do_facet mds1 $LCTL set_param fail_loc=0x328
15906         do_facet mds1 $LCTL set_param fail_val=500
15907
15908         $LCTL set_param debug=+trace
15909
15910         local nr=600
15911         createmany -o $DIR/$tdir/f $nr &
15912         local create_pid=$!
15913
15914         echo "Sleep $TIMEOUT seconds ..."
15915         sleep $TIMEOUT
15916         if ! ps -p $create_pid  > /dev/null 2>&1; then
15917                 do_facet mds1 $LCTL set_param fail_loc=0
15918                 do_facet mds1 $LCTL set_param fail_val=0
15919                 do_facet mds1 $LCTL set_param \
15920                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15921                 error "createmany finished incorrectly!"
15922         fi
15923         do_facet mds1 $LCTL set_param fail_loc=0
15924         do_facet mds1 $LCTL set_param fail_val=0
15925         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15926         wait $create_pid || return 1
15927
15928         unlinkmany $DIR/$tdir/f $nr
15929 }
15930 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15931
15932 test_135() {
15933         remote_mds_nodsh && skip "remote MDS with nodsh"
15934         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15935                 skip "Need MDS version at least 2.13.50"
15936         local fname
15937
15938         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15939
15940 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15941         #set only one record at plain llog
15942         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15943
15944         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15945
15946         #fill already existed plain llog each 64767
15947         #wrapping whole catalog
15948         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15949
15950         createmany -o $DIR/$tdir/$tfile_ 64700
15951         for (( i = 0; i < 64700; i = i + 2 ))
15952         do
15953                 rm $DIR/$tdir/$tfile_$i &
15954                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15955                 local pid=$!
15956                 wait $pid
15957         done
15958
15959         #waiting osp synchronization
15960         wait_delete_completed
15961 }
15962 run_test 135 "Race catalog processing"
15963
15964 test_136() {
15965         remote_mds_nodsh && skip "remote MDS with nodsh"
15966         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15967                 skip "Need MDS version at least 2.13.50"
15968         local fname
15969
15970         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15971         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15972         #set only one record at plain llog
15973 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15974         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15975
15976         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15977
15978         #fill already existed 2 plain llogs each 64767
15979         #wrapping whole catalog
15980         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15981         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15982         wait_delete_completed
15983
15984         createmany -o $DIR/$tdir/$tfile_ 10
15985         sleep 25
15986
15987         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15988         for (( i = 0; i < 10; i = i + 3 ))
15989         do
15990                 rm $DIR/$tdir/$tfile_$i &
15991                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15992                 local pid=$!
15993                 wait $pid
15994                 sleep 7
15995                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15996         done
15997
15998         #waiting osp synchronization
15999         wait_delete_completed
16000 }
16001 run_test 136 "Race catalog processing 2"
16002
16003 test_140() { #bug-17379
16004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16005
16006         test_mkdir $DIR/$tdir
16007         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16008         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16009
16010         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16011         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16012         local i=0
16013         while i=$((i + 1)); do
16014                 test_mkdir $i
16015                 cd $i || error "Changing to $i"
16016                 ln -s ../stat stat || error "Creating stat symlink"
16017                 # Read the symlink until ELOOP present,
16018                 # not LBUGing the system is considered success,
16019                 # we didn't overrun the stack.
16020                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16021                 if [ $ret -ne 0 ]; then
16022                         if [ $ret -eq 40 ]; then
16023                                 break  # -ELOOP
16024                         else
16025                                 error "Open stat symlink"
16026                                         return
16027                         fi
16028                 fi
16029         done
16030         i=$((i - 1))
16031         echo "The symlink depth = $i"
16032         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16033                 error "Invalid symlink depth"
16034
16035         # Test recursive symlink
16036         ln -s symlink_self symlink_self
16037         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16038         echo "open symlink_self returns $ret"
16039         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16040 }
16041 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16042
16043 test_150a() {
16044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16045
16046         local TF="$TMP/$tfile"
16047
16048         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16049         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16050         cp $TF $DIR/$tfile
16051         cancel_lru_locks $OSC
16052         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16053         remount_client $MOUNT
16054         df -P $MOUNT
16055         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16056
16057         $TRUNCATE $TF 6000
16058         $TRUNCATE $DIR/$tfile 6000
16059         cancel_lru_locks $OSC
16060         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16061
16062         echo "12345" >>$TF
16063         echo "12345" >>$DIR/$tfile
16064         cancel_lru_locks $OSC
16065         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16066
16067         echo "12345" >>$TF
16068         echo "12345" >>$DIR/$tfile
16069         cancel_lru_locks $OSC
16070         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16071 }
16072 run_test 150a "truncate/append tests"
16073
16074 test_150b() {
16075         check_set_fallocate_or_skip
16076         local out
16077
16078         touch $DIR/$tfile
16079         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16080         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16081                 skip_eopnotsupp "$out|check_fallocate failed"
16082 }
16083 run_test 150b "Verify fallocate (prealloc) functionality"
16084
16085 test_150bb() {
16086         check_set_fallocate_or_skip
16087
16088         touch $DIR/$tfile
16089         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16090         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16091         > $DIR/$tfile
16092         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16093         # precomputed md5sum for 20MB of zeroes
16094         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16095         local sum=($(md5sum $DIR/$tfile))
16096
16097         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16098
16099         check_set_fallocate 1
16100
16101         > $DIR/$tfile
16102         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16103         sum=($(md5sum $DIR/$tfile))
16104
16105         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16106 }
16107 run_test 150bb "Verify fallocate modes both zero space"
16108
16109 test_150c() {
16110         check_set_fallocate_or_skip
16111         local striping="-c2"
16112
16113         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16114         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16115         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16116         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16117         local want=$((OSTCOUNT * 1048576))
16118
16119         # Must allocate all requested space, not more than 5% extra
16120         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16121                 error "bytes $bytes is not $want"
16122
16123         rm -f $DIR/$tfile
16124
16125         echo "verify fallocate on PFL file"
16126
16127         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16128
16129         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16130                 error "Create $DIR/$tfile failed"
16131         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16132         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16133         want=$((512 * 1048576))
16134
16135         # Must allocate all requested space, not more than 5% extra
16136         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16137                 error "bytes $bytes is not $want"
16138 }
16139 run_test 150c "Verify fallocate Size and Blocks"
16140
16141 test_150d() {
16142         check_set_fallocate_or_skip
16143         local striping="-c2"
16144
16145         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16146
16147         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16148         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16149                 error "setstripe failed"
16150         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16151         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16152         local want=$((OSTCOUNT * 1048576))
16153
16154         # Must allocate all requested space, not more than 5% extra
16155         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16156                 error "bytes $bytes is not $want"
16157 }
16158 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16159
16160 test_150e() {
16161         check_set_fallocate_or_skip
16162
16163         echo "df before:"
16164         $LFS df
16165         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16166         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16167                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16168
16169         # Find OST with Minimum Size
16170         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16171                        sort -un | head -1)
16172
16173         # Get 100MB per OST of the available space to reduce run time
16174         # else 60% of the available space if we are running SLOW tests
16175         if [ $SLOW == "no" ]; then
16176                 local space=$((1024 * 100 * OSTCOUNT))
16177         else
16178                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16179         fi
16180
16181         fallocate -l${space}k $DIR/$tfile ||
16182                 error "fallocate ${space}k $DIR/$tfile failed"
16183         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16184
16185         # get size immediately after fallocate. This should be correctly
16186         # updated
16187         local size=$(stat -c '%s' $DIR/$tfile)
16188         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16189
16190         # Sleep for a while for statfs to get updated. And not pull from cache.
16191         sleep 2
16192
16193         echo "df after fallocate:"
16194         $LFS df
16195
16196         (( size / 1024 == space )) || error "size $size != requested $space"
16197         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16198                 error "used $used < space $space"
16199
16200         rm $DIR/$tfile || error "rm failed"
16201         sync
16202         wait_delete_completed
16203
16204         echo "df after unlink:"
16205         $LFS df
16206 }
16207 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16208
16209 test_150f() {
16210         local size
16211         local blocks
16212         local want_size_before=20480 # in bytes
16213         local want_blocks_before=40 # 512 sized blocks
16214         local want_blocks_after=24  # 512 sized blocks
16215         local length=$(((want_blocks_before - want_blocks_after) * 512))
16216
16217         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16218                 skip "need at least 2.14.0 for fallocate punch"
16219
16220         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16221                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16222         fi
16223
16224         check_set_fallocate_or_skip
16225         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16226
16227         [[ "x$DOM" == "xyes" ]] &&
16228                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16229
16230         echo "Verify fallocate punch: Range within the file range"
16231         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16232                 error "dd failed for bs 4096 and count 5"
16233
16234         # Call fallocate with punch range which is within the file range
16235         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16236                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16237         # client must see changes immediately after fallocate
16238         size=$(stat -c '%s' $DIR/$tfile)
16239         blocks=$(stat -c '%b' $DIR/$tfile)
16240
16241         # Verify punch worked.
16242         (( blocks == want_blocks_after )) ||
16243                 error "punch failed: blocks $blocks != $want_blocks_after"
16244
16245         (( size == want_size_before )) ||
16246                 error "punch failed: size $size != $want_size_before"
16247
16248         # Verify there is hole in file
16249         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16250         # precomputed md5sum
16251         local expect="4a9a834a2db02452929c0a348273b4aa"
16252
16253         cksum=($(md5sum $DIR/$tfile))
16254         [[ "${cksum[0]}" == "$expect" ]] ||
16255                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16256
16257         # Start second sub-case for fallocate punch.
16258         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16259         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16260                 error "dd failed for bs 4096 and count 5"
16261
16262         # Punch range less than block size will have no change in block count
16263         want_blocks_after=40  # 512 sized blocks
16264
16265         # Punch overlaps two blocks and less than blocksize
16266         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16267                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16268         size=$(stat -c '%s' $DIR/$tfile)
16269         blocks=$(stat -c '%b' $DIR/$tfile)
16270
16271         # Verify punch worked.
16272         (( blocks == want_blocks_after )) ||
16273                 error "punch failed: blocks $blocks != $want_blocks_after"
16274
16275         (( size == want_size_before )) ||
16276                 error "punch failed: size $size != $want_size_before"
16277
16278         # Verify if range is really zero'ed out. We expect Zeros.
16279         # precomputed md5sum
16280         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16281         cksum=($(md5sum $DIR/$tfile))
16282         [[ "${cksum[0]}" == "$expect" ]] ||
16283                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16284 }
16285 run_test 150f "Verify fallocate punch functionality"
16286
16287 test_150g() {
16288         local space
16289         local size
16290         local blocks
16291         local blocks_after
16292         local size_after
16293         local BS=4096 # Block size in bytes
16294
16295         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16296                 skip "need at least 2.14.0 for fallocate punch"
16297
16298         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16299                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16300         fi
16301
16302         check_set_fallocate_or_skip
16303         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16304
16305         if [[ "x$DOM" == "xyes" ]]; then
16306                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16307                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16308         else
16309                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16310                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16311         fi
16312
16313         # Get 100MB per OST of the available space to reduce run time
16314         # else 60% of the available space if we are running SLOW tests
16315         if [ $SLOW == "no" ]; then
16316                 space=$((1024 * 100 * OSTCOUNT))
16317         else
16318                 # Find OST with Minimum Size
16319                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16320                         sort -un | head -1)
16321                 echo "min size OST: $space"
16322                 space=$(((space * 60)/100 * OSTCOUNT))
16323         fi
16324         # space in 1k units, round to 4k blocks
16325         local blkcount=$((space * 1024 / $BS))
16326
16327         echo "Verify fallocate punch: Very large Range"
16328         fallocate -l${space}k $DIR/$tfile ||
16329                 error "fallocate ${space}k $DIR/$tfile failed"
16330         # write 1M at the end, start and in the middle
16331         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16332                 error "dd failed: bs $BS count 256"
16333         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16334                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16335         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16336                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16337
16338         # Gather stats.
16339         size=$(stat -c '%s' $DIR/$tfile)
16340
16341         # gather punch length.
16342         local punch_size=$((size - (BS * 2)))
16343
16344         echo "punch_size = $punch_size"
16345         echo "size - punch_size: $((size - punch_size))"
16346         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16347
16348         # Call fallocate to punch all except 2 blocks. We leave the
16349         # first and the last block
16350         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16351         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16352                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16353
16354         size_after=$(stat -c '%s' $DIR/$tfile)
16355         blocks_after=$(stat -c '%b' $DIR/$tfile)
16356
16357         # Verify punch worked.
16358         # Size should be kept
16359         (( size == size_after )) ||
16360                 error "punch failed: size $size != $size_after"
16361
16362         # two 4k data blocks to remain plus possible 1 extra extent block
16363         (( blocks_after <= ((BS / 512) * 3) )) ||
16364                 error "too many blocks remains: $blocks_after"
16365
16366         # Verify that file has hole between the first and the last blocks
16367         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16368         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16369
16370         echo "Hole at [$hole_start, $hole_end)"
16371         (( hole_start == BS )) ||
16372                 error "no hole at offset $BS after punch"
16373
16374         (( hole_end == BS + punch_size )) ||
16375                 error "data at offset $hole_end < $((BS + punch_size))"
16376 }
16377 run_test 150g "Verify fallocate punch on large range"
16378
16379 test_150h() {
16380         local file=$DIR/$tfile
16381         local size
16382
16383         check_set_fallocate_or_skip
16384         statx_supported || skip_env "Test must be statx() syscall supported"
16385
16386         # fallocate() does not update the size information on the MDT
16387         fallocate -l 16K $file || error "failed to fallocate $file"
16388         cancel_lru_locks $OSC
16389         # STATX with cached-always mode will not send glimpse RPCs to OST,
16390         # it uses the caching attrs on the client side as much as possible.
16391         size=$($STATX --cached=always -c %s $file)
16392         [ $size == 16384 ] ||
16393                 error "size after fallocate() is $size, expected 16384"
16394 }
16395 run_test 150h "Verify extend fallocate updates the file size"
16396
16397 #LU-2902 roc_hit was not able to read all values from lproc
16398 function roc_hit_init() {
16399         local list=$(comma_list $(osts_nodes))
16400         local dir=$DIR/$tdir-check
16401         local file=$dir/$tfile
16402         local BEFORE
16403         local AFTER
16404         local idx
16405
16406         test_mkdir $dir
16407         #use setstripe to do a write to every ost
16408         for i in $(seq 0 $((OSTCOUNT-1))); do
16409                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16410                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16411                 idx=$(printf %04x $i)
16412                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16413                         awk '$1 == "cache_access" {sum += $7}
16414                                 END { printf("%0.0f", sum) }')
16415
16416                 cancel_lru_locks osc
16417                 cat $file >/dev/null
16418
16419                 AFTER=$(get_osd_param $list *OST*$idx stats |
16420                         awk '$1 == "cache_access" {sum += $7}
16421                                 END { printf("%0.0f", sum) }')
16422
16423                 echo BEFORE:$BEFORE AFTER:$AFTER
16424                 if ! let "AFTER - BEFORE == 4"; then
16425                         rm -rf $dir
16426                         error "roc_hit is not safe to use"
16427                 fi
16428                 rm $file
16429         done
16430
16431         rm -rf $dir
16432 }
16433
16434 function roc_hit() {
16435         local list=$(comma_list $(osts_nodes))
16436         echo $(get_osd_param $list '' stats |
16437                 awk '$1 == "cache_hit" {sum += $7}
16438                         END { printf("%0.0f", sum) }')
16439 }
16440
16441 function set_cache() {
16442         local on=1
16443
16444         if [ "$2" == "off" ]; then
16445                 on=0;
16446         fi
16447         local list=$(comma_list $(osts_nodes))
16448         set_osd_param $list '' $1_cache_enable $on
16449
16450         cancel_lru_locks osc
16451 }
16452
16453 test_151() {
16454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16455         remote_ost_nodsh && skip "remote OST with nodsh"
16456         (( CLIENT_VERSION == OST1_VERSION )) ||
16457                 skip "LU-13081: no interop testing for OSS cache"
16458
16459         local CPAGES=3
16460         local list=$(comma_list $(osts_nodes))
16461
16462         # check whether obdfilter is cache capable at all
16463         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16464                 skip "not cache-capable obdfilter"
16465         fi
16466
16467         # check cache is enabled on all obdfilters
16468         if get_osd_param $list '' read_cache_enable | grep 0; then
16469                 skip "oss cache is disabled"
16470         fi
16471
16472         set_osd_param $list '' writethrough_cache_enable 1
16473
16474         # check write cache is enabled on all obdfilters
16475         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16476                 skip "oss write cache is NOT enabled"
16477         fi
16478
16479         roc_hit_init
16480
16481         #define OBD_FAIL_OBD_NO_LRU  0x609
16482         do_nodes $list $LCTL set_param fail_loc=0x609
16483
16484         # pages should be in the case right after write
16485         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16486                 error "dd failed"
16487
16488         local BEFORE=$(roc_hit)
16489         cancel_lru_locks osc
16490         cat $DIR/$tfile >/dev/null
16491         local AFTER=$(roc_hit)
16492
16493         do_nodes $list $LCTL set_param fail_loc=0
16494
16495         if ! let "AFTER - BEFORE == CPAGES"; then
16496                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16497         fi
16498
16499         cancel_lru_locks osc
16500         # invalidates OST cache
16501         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16502         set_osd_param $list '' read_cache_enable 0
16503         cat $DIR/$tfile >/dev/null
16504
16505         # now data shouldn't be found in the cache
16506         BEFORE=$(roc_hit)
16507         cancel_lru_locks osc
16508         cat $DIR/$tfile >/dev/null
16509         AFTER=$(roc_hit)
16510         if let "AFTER - BEFORE != 0"; then
16511                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16512         fi
16513
16514         set_osd_param $list '' read_cache_enable 1
16515         rm -f $DIR/$tfile
16516 }
16517 run_test 151 "test cache on oss and controls ==============================="
16518
16519 test_152() {
16520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16521
16522         local TF="$TMP/$tfile"
16523
16524         # simulate ENOMEM during write
16525 #define OBD_FAIL_OST_NOMEM      0x226
16526         lctl set_param fail_loc=0x80000226
16527         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16528         cp $TF $DIR/$tfile
16529         sync || error "sync failed"
16530         lctl set_param fail_loc=0
16531
16532         # discard client's cache
16533         cancel_lru_locks osc
16534
16535         # simulate ENOMEM during read
16536         lctl set_param fail_loc=0x80000226
16537         cmp $TF $DIR/$tfile || error "cmp failed"
16538         lctl set_param fail_loc=0
16539
16540         rm -f $TF
16541 }
16542 run_test 152 "test read/write with enomem ============================"
16543
16544 test_153() {
16545         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16546 }
16547 run_test 153 "test if fdatasync does not crash ======================="
16548
16549 dot_lustre_fid_permission_check() {
16550         local fid=$1
16551         local ffid=$MOUNT/.lustre/fid/$fid
16552         local test_dir=$2
16553
16554         echo "stat fid $fid"
16555         stat $ffid || error "stat $ffid failed."
16556         echo "touch fid $fid"
16557         touch $ffid || error "touch $ffid failed."
16558         echo "write to fid $fid"
16559         cat /etc/hosts > $ffid || error "write $ffid failed."
16560         echo "read fid $fid"
16561         diff /etc/hosts $ffid || error "read $ffid failed."
16562         echo "append write to fid $fid"
16563         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16564         echo "rename fid $fid"
16565         mv $ffid $test_dir/$tfile.1 &&
16566                 error "rename $ffid to $tfile.1 should fail."
16567         touch $test_dir/$tfile.1
16568         mv $test_dir/$tfile.1 $ffid &&
16569                 error "rename $tfile.1 to $ffid should fail."
16570         rm -f $test_dir/$tfile.1
16571         echo "truncate fid $fid"
16572         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16573         echo "link fid $fid"
16574         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16575         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16576                 id $USER0 || skip_env "missing user $USER0"
16577                 echo "setfacl fid $fid"
16578                 setfacl -R -m u:$USER0:rwx $ffid ||
16579                         error "setfacl $ffid failed"
16580                 echo "getfacl fid $fid"
16581                 getfacl $ffid || error "getfacl $ffid failed."
16582         fi
16583         echo "unlink fid $fid"
16584         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16585         echo "mknod fid $fid"
16586         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16587
16588         fid=[0xf00000400:0x1:0x0]
16589         ffid=$MOUNT/.lustre/fid/$fid
16590
16591         echo "stat non-exist fid $fid"
16592         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16593         echo "write to non-exist fid $fid"
16594         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16595         echo "link new fid $fid"
16596         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16597
16598         mkdir -p $test_dir/$tdir
16599         touch $test_dir/$tdir/$tfile
16600         fid=$($LFS path2fid $test_dir/$tdir)
16601         rc=$?
16602         [ $rc -ne 0 ] &&
16603                 error "error: could not get fid for $test_dir/$dir/$tfile."
16604
16605         ffid=$MOUNT/.lustre/fid/$fid
16606
16607         echo "ls $fid"
16608         ls $ffid || error "ls $ffid failed."
16609         echo "touch $fid/$tfile.1"
16610         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16611
16612         echo "touch $MOUNT/.lustre/fid/$tfile"
16613         touch $MOUNT/.lustre/fid/$tfile && \
16614                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16615
16616         echo "setxattr to $MOUNT/.lustre/fid"
16617         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16618
16619         echo "listxattr for $MOUNT/.lustre/fid"
16620         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16621
16622         echo "delxattr from $MOUNT/.lustre/fid"
16623         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16624
16625         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16626         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16627                 error "touch invalid fid should fail."
16628
16629         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16630         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16631                 error "touch non-normal fid should fail."
16632
16633         echo "rename $tdir to $MOUNT/.lustre/fid"
16634         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16635                 error "rename to $MOUNT/.lustre/fid should fail."
16636
16637         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16638         then            # LU-3547
16639                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16640                 local new_obf_mode=777
16641
16642                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16643                 chmod $new_obf_mode $DIR/.lustre/fid ||
16644                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16645
16646                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16647                 [ $obf_mode -eq $new_obf_mode ] ||
16648                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16649
16650                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16651                 chmod $old_obf_mode $DIR/.lustre/fid ||
16652                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16653         fi
16654
16655         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16656         fid=$($LFS path2fid $test_dir/$tfile-2)
16657
16658         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16659         then # LU-5424
16660                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16661                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16662                         error "create lov data thru .lustre failed"
16663         fi
16664         echo "cp /etc/passwd $test_dir/$tfile-2"
16665         cp /etc/passwd $test_dir/$tfile-2 ||
16666                 error "copy to $test_dir/$tfile-2 failed."
16667         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16668         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16669                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16670
16671         rm -rf $test_dir/tfile.lnk
16672         rm -rf $test_dir/$tfile-2
16673 }
16674
16675 test_154A() {
16676         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16677                 skip "Need MDS version at least 2.4.1"
16678
16679         local tf=$DIR/$tfile
16680         touch $tf
16681
16682         local fid=$($LFS path2fid $tf)
16683         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16684
16685         # check that we get the same pathname back
16686         local rootpath
16687         local found
16688         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16689                 echo "$rootpath $fid"
16690                 found=$($LFS fid2path $rootpath "$fid")
16691                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16692                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16693         done
16694
16695         # check wrong root path format
16696         rootpath=$MOUNT"_wrong"
16697         found=$($LFS fid2path $rootpath "$fid")
16698         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16699 }
16700 run_test 154A "lfs path2fid and fid2path basic checks"
16701
16702 test_154B() {
16703         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16704                 skip "Need MDS version at least 2.4.1"
16705
16706         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16707         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16708         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16709         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16710
16711         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16712         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16713
16714         # check that we get the same pathname
16715         echo "PFID: $PFID, name: $name"
16716         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16717         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16718         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16719                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16720
16721         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16722 }
16723 run_test 154B "verify the ll_decode_linkea tool"
16724
16725 test_154a() {
16726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16727         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16728         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16729                 skip "Need MDS version at least 2.2.51"
16730         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16731
16732         cp /etc/hosts $DIR/$tfile
16733
16734         fid=$($LFS path2fid $DIR/$tfile)
16735         rc=$?
16736         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16737
16738         dot_lustre_fid_permission_check "$fid" $DIR ||
16739                 error "dot lustre permission check $fid failed"
16740
16741         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16742
16743         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16744
16745         touch $MOUNT/.lustre/file &&
16746                 error "creation is not allowed under .lustre"
16747
16748         mkdir $MOUNT/.lustre/dir &&
16749                 error "mkdir is not allowed under .lustre"
16750
16751         rm -rf $DIR/$tfile
16752 }
16753 run_test 154a "Open-by-FID"
16754
16755 test_154b() {
16756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16757         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16759         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16760                 skip "Need MDS version at least 2.2.51"
16761
16762         local remote_dir=$DIR/$tdir/remote_dir
16763         local MDTIDX=1
16764         local rc=0
16765
16766         mkdir -p $DIR/$tdir
16767         $LFS mkdir -i $MDTIDX $remote_dir ||
16768                 error "create remote directory failed"
16769
16770         cp /etc/hosts $remote_dir/$tfile
16771
16772         fid=$($LFS path2fid $remote_dir/$tfile)
16773         rc=$?
16774         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16775
16776         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16777                 error "dot lustre permission check $fid failed"
16778         rm -rf $DIR/$tdir
16779 }
16780 run_test 154b "Open-by-FID for remote directory"
16781
16782 test_154c() {
16783         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16784                 skip "Need MDS version at least 2.4.1"
16785
16786         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16787         local FID1=$($LFS path2fid $DIR/$tfile.1)
16788         local FID2=$($LFS path2fid $DIR/$tfile.2)
16789         local FID3=$($LFS path2fid $DIR/$tfile.3)
16790
16791         local N=1
16792         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16793                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16794                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16795                 local want=FID$N
16796                 [ "$FID" = "${!want}" ] ||
16797                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16798                 N=$((N + 1))
16799         done
16800
16801         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16802         do
16803                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16804                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16805                 N=$((N + 1))
16806         done
16807 }
16808 run_test 154c "lfs path2fid and fid2path multiple arguments"
16809
16810 test_154d() {
16811         remote_mds_nodsh && skip "remote MDS with nodsh"
16812         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16813                 skip "Need MDS version at least 2.5.53"
16814
16815         if remote_mds; then
16816                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16817         else
16818                 nid="0@lo"
16819         fi
16820         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16821         local fd
16822         local cmd
16823
16824         rm -f $DIR/$tfile
16825         touch $DIR/$tfile
16826
16827         local fid=$($LFS path2fid $DIR/$tfile)
16828         # Open the file
16829         fd=$(free_fd)
16830         cmd="exec $fd<$DIR/$tfile"
16831         eval $cmd
16832         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16833         echo "$fid_list" | grep "$fid"
16834         rc=$?
16835
16836         cmd="exec $fd>/dev/null"
16837         eval $cmd
16838         if [ $rc -ne 0 ]; then
16839                 error "FID $fid not found in open files list $fid_list"
16840         fi
16841 }
16842 run_test 154d "Verify open file fid"
16843
16844 test_154e()
16845 {
16846         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16847                 skip "Need MDS version at least 2.6.50"
16848
16849         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16850                 error ".lustre returned by readdir"
16851         fi
16852 }
16853 run_test 154e ".lustre is not returned by readdir"
16854
16855 test_154f() {
16856         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16857
16858         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16859         mkdir_on_mdt0 $DIR/$tdir
16860         # test dirs inherit from its stripe
16861         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16862         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16863         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16864         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16865         touch $DIR/f
16866
16867         # get fid of parents
16868         local FID0=$($LFS path2fid $DIR/$tdir)
16869         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16870         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16871         local FID3=$($LFS path2fid $DIR)
16872
16873         # check that path2fid --parents returns expected <parent_fid>/name
16874         # 1) test for a directory (single parent)
16875         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16876         [ "$parent" == "$FID0/foo1" ] ||
16877                 error "expected parent: $FID0/foo1, got: $parent"
16878
16879         # 2) test for a file with nlink > 1 (multiple parents)
16880         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16881         echo "$parent" | grep -F "$FID1/$tfile" ||
16882                 error "$FID1/$tfile not returned in parent list"
16883         echo "$parent" | grep -F "$FID2/link" ||
16884                 error "$FID2/link not returned in parent list"
16885
16886         # 3) get parent by fid
16887         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16888         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16889         echo "$parent" | grep -F "$FID1/$tfile" ||
16890                 error "$FID1/$tfile not returned in parent list (by fid)"
16891         echo "$parent" | grep -F "$FID2/link" ||
16892                 error "$FID2/link not returned in parent list (by fid)"
16893
16894         # 4) test for entry in root directory
16895         parent=$($LFS path2fid --parents $DIR/f)
16896         echo "$parent" | grep -F "$FID3/f" ||
16897                 error "$FID3/f not returned in parent list"
16898
16899         # 5) test it on root directory
16900         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16901                 error "$MOUNT should not have parents"
16902
16903         # enable xattr caching and check that linkea is correctly updated
16904         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16905         save_lustre_params client "llite.*.xattr_cache" > $save
16906         lctl set_param llite.*.xattr_cache 1
16907
16908         # 6.1) linkea update on rename
16909         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16910
16911         # get parents by fid
16912         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16913         # foo1 should no longer be returned in parent list
16914         echo "$parent" | grep -F "$FID1" &&
16915                 error "$FID1 should no longer be in parent list"
16916         # the new path should appear
16917         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16918                 error "$FID2/$tfile.moved is not in parent list"
16919
16920         # 6.2) linkea update on unlink
16921         rm -f $DIR/$tdir/foo2/link
16922         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16923         # foo2/link should no longer be returned in parent list
16924         echo "$parent" | grep -F "$FID2/link" &&
16925                 error "$FID2/link should no longer be in parent list"
16926         true
16927
16928         rm -f $DIR/f
16929         restore_lustre_params < $save
16930         rm -f $save
16931 }
16932 run_test 154f "get parent fids by reading link ea"
16933
16934 test_154g()
16935 {
16936         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16937            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16938                 skip "Need MDS version at least 2.6.92"
16939
16940         mkdir_on_mdt0 $DIR/$tdir
16941         llapi_fid_test -d $DIR/$tdir
16942 }
16943 run_test 154g "various llapi FID tests"
16944
16945 test_154h()
16946 {
16947         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16948                 skip "Need client at least version 2.15.55.1"
16949
16950         # Create an empty file
16951         touch $DIR/$tfile
16952
16953         # Get FID (interactive mode) and save under $TMP/$tfile.log
16954         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16955                 path2fid $DIR/$tfile
16956         EOF
16957
16958         fid=$(cat $TMP/$tfile.log)
16959         # $fid should not be empty
16960         [[ ! -z $fid ]] || error "FID is empty"
16961         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16962 }
16963 run_test 154h "Verify interactive path2fid"
16964
16965 test_155_small_load() {
16966     local temp=$TMP/$tfile
16967     local file=$DIR/$tfile
16968
16969     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16970         error "dd of=$temp bs=6096 count=1 failed"
16971     cp $temp $file
16972     cancel_lru_locks $OSC
16973     cmp $temp $file || error "$temp $file differ"
16974
16975     $TRUNCATE $temp 6000
16976     $TRUNCATE $file 6000
16977     cmp $temp $file || error "$temp $file differ (truncate1)"
16978
16979     echo "12345" >>$temp
16980     echo "12345" >>$file
16981     cmp $temp $file || error "$temp $file differ (append1)"
16982
16983     echo "12345" >>$temp
16984     echo "12345" >>$file
16985     cmp $temp $file || error "$temp $file differ (append2)"
16986
16987     rm -f $temp $file
16988     true
16989 }
16990
16991 test_155_big_load() {
16992         remote_ost_nodsh && skip "remote OST with nodsh"
16993
16994         local temp=$TMP/$tfile
16995         local file=$DIR/$tfile
16996
16997         free_min_max
16998         local cache_size=$(do_facet ost$((MAXI+1)) \
16999                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17000
17001         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17002         # pre-set value
17003         if [ -z "$cache_size" ]; then
17004                 cache_size=256
17005         fi
17006         local large_file_size=$((cache_size * 2))
17007
17008         echo "OSS cache size: $cache_size KB"
17009         echo "Large file size: $large_file_size KB"
17010
17011         [ $MAXV -le $large_file_size ] &&
17012                 skip_env "max available OST size needs > $large_file_size KB"
17013
17014         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17015
17016         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17017                 error "dd of=$temp bs=$large_file_size count=1k failed"
17018         cp $temp $file
17019         ls -lh $temp $file
17020         cancel_lru_locks osc
17021         cmp $temp $file || error "$temp $file differ"
17022
17023         rm -f $temp $file
17024         true
17025 }
17026
17027 save_writethrough() {
17028         local facets=$(get_facets OST)
17029
17030         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17031 }
17032
17033 test_155a() {
17034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17035
17036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17037
17038         save_writethrough $p
17039
17040         set_cache read on
17041         set_cache writethrough on
17042         test_155_small_load
17043         restore_lustre_params < $p
17044         rm -f $p
17045 }
17046 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17047
17048 test_155b() {
17049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17050
17051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17052
17053         save_writethrough $p
17054
17055         set_cache read on
17056         set_cache writethrough off
17057         test_155_small_load
17058         restore_lustre_params < $p
17059         rm -f $p
17060 }
17061 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17062
17063 test_155c() {
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065
17066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17067
17068         save_writethrough $p
17069
17070         set_cache read off
17071         set_cache writethrough on
17072         test_155_small_load
17073         restore_lustre_params < $p
17074         rm -f $p
17075 }
17076 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17077
17078 test_155d() {
17079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17080
17081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17082
17083         save_writethrough $p
17084
17085         set_cache read off
17086         set_cache writethrough off
17087         test_155_small_load
17088         restore_lustre_params < $p
17089         rm -f $p
17090 }
17091 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17092
17093 test_155e() {
17094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17095
17096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17097
17098         save_writethrough $p
17099
17100         set_cache read on
17101         set_cache writethrough on
17102         test_155_big_load
17103         restore_lustre_params < $p
17104         rm -f $p
17105 }
17106 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17107
17108 test_155f() {
17109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17110
17111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17112
17113         save_writethrough $p
17114
17115         set_cache read on
17116         set_cache writethrough off
17117         test_155_big_load
17118         restore_lustre_params < $p
17119         rm -f $p
17120 }
17121 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17122
17123 test_155g() {
17124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17125
17126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17127
17128         save_writethrough $p
17129
17130         set_cache read off
17131         set_cache writethrough on
17132         test_155_big_load
17133         restore_lustre_params < $p
17134         rm -f $p
17135 }
17136 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17137
17138 test_155h() {
17139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17140
17141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17142
17143         save_writethrough $p
17144
17145         set_cache read off
17146         set_cache writethrough off
17147         test_155_big_load
17148         restore_lustre_params < $p
17149         rm -f $p
17150 }
17151 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17152
17153 test_156() {
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155         remote_ost_nodsh && skip "remote OST with nodsh"
17156         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17157                 skip "stats not implemented on old servers"
17158         [ "$ost1_FSTYPE" = "zfs" ] &&
17159                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17160         (( CLIENT_VERSION == OST1_VERSION )) ||
17161                 skip "LU-13081: no interop testing for OSS cache"
17162
17163         local CPAGES=3
17164         local BEFORE
17165         local AFTER
17166         local file="$DIR/$tfile"
17167         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17168
17169         save_writethrough $p
17170         roc_hit_init
17171
17172         log "Turn on read and write cache"
17173         set_cache read on
17174         set_cache writethrough on
17175
17176         log "Write data and read it back."
17177         log "Read should be satisfied from the cache."
17178         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17179         BEFORE=$(roc_hit)
17180         cancel_lru_locks osc
17181         cat $file >/dev/null
17182         AFTER=$(roc_hit)
17183         if ! let "AFTER - BEFORE == CPAGES"; then
17184                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17185         else
17186                 log "cache hits: before: $BEFORE, after: $AFTER"
17187         fi
17188
17189         log "Read again; it should be satisfied from the cache."
17190         BEFORE=$AFTER
17191         cancel_lru_locks osc
17192         cat $file >/dev/null
17193         AFTER=$(roc_hit)
17194         if ! let "AFTER - BEFORE == CPAGES"; then
17195                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17196         else
17197                 log "cache hits:: before: $BEFORE, after: $AFTER"
17198         fi
17199
17200         log "Turn off the read cache and turn on the write cache"
17201         set_cache read off
17202         set_cache writethrough on
17203
17204         log "Read again; it should be satisfied from the cache."
17205         BEFORE=$(roc_hit)
17206         cancel_lru_locks osc
17207         cat $file >/dev/null
17208         AFTER=$(roc_hit)
17209         if ! let "AFTER - BEFORE == CPAGES"; then
17210                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17211         else
17212                 log "cache hits:: before: $BEFORE, after: $AFTER"
17213         fi
17214
17215         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17216                 # > 2.12.56 uses pagecache if cached
17217                 log "Read again; it should not be satisfied from the cache."
17218                 BEFORE=$AFTER
17219                 cancel_lru_locks osc
17220                 cat $file >/dev/null
17221                 AFTER=$(roc_hit)
17222                 if ! let "AFTER - BEFORE == 0"; then
17223                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17224                 else
17225                         log "cache hits:: before: $BEFORE, after: $AFTER"
17226                 fi
17227         fi
17228
17229         log "Write data and read it back."
17230         log "Read should be satisfied from the cache."
17231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17232         BEFORE=$(roc_hit)
17233         cancel_lru_locks osc
17234         cat $file >/dev/null
17235         AFTER=$(roc_hit)
17236         if ! let "AFTER - BEFORE == CPAGES"; then
17237                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17238         else
17239                 log "cache hits:: before: $BEFORE, after: $AFTER"
17240         fi
17241
17242         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17243                 # > 2.12.56 uses pagecache if cached
17244                 log "Read again; it should not be satisfied from the cache."
17245                 BEFORE=$AFTER
17246                 cancel_lru_locks osc
17247                 cat $file >/dev/null
17248                 AFTER=$(roc_hit)
17249                 if ! let "AFTER - BEFORE == 0"; then
17250                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17251                 else
17252                         log "cache hits:: before: $BEFORE, after: $AFTER"
17253                 fi
17254         fi
17255
17256         log "Turn off read and write cache"
17257         set_cache read off
17258         set_cache writethrough off
17259
17260         log "Write data and read it back"
17261         log "It should not be satisfied from the cache."
17262         rm -f $file
17263         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17264         cancel_lru_locks osc
17265         BEFORE=$(roc_hit)
17266         cat $file >/dev/null
17267         AFTER=$(roc_hit)
17268         if ! let "AFTER - BEFORE == 0"; then
17269                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17270         else
17271                 log "cache hits:: before: $BEFORE, after: $AFTER"
17272         fi
17273
17274         log "Turn on the read cache and turn off the write cache"
17275         set_cache read on
17276         set_cache writethrough off
17277
17278         log "Write data and read it back"
17279         log "It should not be satisfied from the cache."
17280         rm -f $file
17281         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17282         BEFORE=$(roc_hit)
17283         cancel_lru_locks osc
17284         cat $file >/dev/null
17285         AFTER=$(roc_hit)
17286         if ! let "AFTER - BEFORE == 0"; then
17287                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17288         else
17289                 log "cache hits:: before: $BEFORE, after: $AFTER"
17290         fi
17291
17292         log "Read again; it should be satisfied from the cache."
17293         BEFORE=$(roc_hit)
17294         cancel_lru_locks osc
17295         cat $file >/dev/null
17296         AFTER=$(roc_hit)
17297         if ! let "AFTER - BEFORE == CPAGES"; then
17298                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17299         else
17300                 log "cache hits:: before: $BEFORE, after: $AFTER"
17301         fi
17302
17303         restore_lustre_params < $p
17304         rm -f $p $file
17305 }
17306 run_test 156 "Verification of tunables"
17307
17308 test_160a() {
17309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17310         remote_mds_nodsh && skip "remote MDS with nodsh"
17311         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17312                 skip "Need MDS version at least 2.2.0"
17313
17314         changelog_register || error "changelog_register failed"
17315         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17316         changelog_users $SINGLEMDS | grep -q $cl_user ||
17317                 error "User $cl_user not found in changelog_users"
17318
17319         mkdir_on_mdt0 $DIR/$tdir
17320
17321         # change something
17322         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17323         changelog_clear 0 || error "changelog_clear failed"
17324         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17325         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17326         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17327         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17328         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17329         rm $DIR/$tdir/pics/desktop.jpg
17330
17331         echo "verifying changelog mask"
17332         changelog_chmask "-MKDIR"
17333         changelog_chmask "-CLOSE"
17334
17335         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17336         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17337
17338         changelog_chmask "+MKDIR"
17339         changelog_chmask "+CLOSE"
17340
17341         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17342         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17343
17344         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17345         CLOSES=$(changelog_dump | grep -c "CLOSE")
17346         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17347         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17348
17349         # verify contents
17350         echo "verifying target fid"
17351         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17352         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17353         [ "$fidc" == "$fidf" ] ||
17354                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17355         echo "verifying parent fid"
17356         # The FID returned from the Changelog may be the directory shard on
17357         # a different MDT, and not the FID returned by path2fid on the parent.
17358         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17359         # since this is what will matter when recreating this file in the tree.
17360         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17361         local pathp=$($LFS fid2path $MOUNT "$fidp")
17362         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17363                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17364
17365         echo "getting records for $cl_user"
17366         changelog_users $SINGLEMDS
17367         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17368         local nclr=3
17369         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17370                 error "changelog_clear failed"
17371         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17372         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17373         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17374                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17375
17376         local min0_rec=$(changelog_users $SINGLEMDS |
17377                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17378         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17379                           awk '{ print $1; exit; }')
17380
17381         changelog_dump | tail -n 5
17382         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17383         [ $first_rec == $((min0_rec + 1)) ] ||
17384                 error "first index should be $min0_rec + 1 not $first_rec"
17385
17386         # LU-3446 changelog index reset on MDT restart
17387         local cur_rec1=$(changelog_users $SINGLEMDS |
17388                          awk '/^current.index:/ { print $NF }')
17389         changelog_clear 0 ||
17390                 error "clear all changelog records for $cl_user failed"
17391         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17392         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17393                 error "Fail to start $SINGLEMDS"
17394         local cur_rec2=$(changelog_users $SINGLEMDS |
17395                          awk '/^current.index:/ { print $NF }')
17396         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17397         [ $cur_rec1 == $cur_rec2 ] ||
17398                 error "current index should be $cur_rec1 not $cur_rec2"
17399
17400         echo "verifying users from this test are deregistered"
17401         changelog_deregister || error "changelog_deregister failed"
17402         changelog_users $SINGLEMDS | grep -q $cl_user &&
17403                 error "User '$cl_user' still in changelog_users"
17404
17405         # lctl get_param -n mdd.*.changelog_users
17406         # current_index: 144
17407         # ID    index (idle seconds)
17408         # cl3   144   (2) mask=<list>
17409         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17410                 # this is the normal case where all users were deregistered
17411                 # make sure no new records are added when no users are present
17412                 local last_rec1=$(changelog_users $SINGLEMDS |
17413                                   awk '/^current.index:/ { print $NF }')
17414                 touch $DIR/$tdir/chloe
17415                 local last_rec2=$(changelog_users $SINGLEMDS |
17416                                   awk '/^current.index:/ { print $NF }')
17417                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17418                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17419         else
17420                 # any changelog users must be leftovers from a previous test
17421                 changelog_users $SINGLEMDS
17422                 echo "other changelog users; can't verify off"
17423         fi
17424 }
17425 run_test 160a "changelog sanity"
17426
17427 test_160b() { # LU-3587
17428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17429         remote_mds_nodsh && skip "remote MDS with nodsh"
17430         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17431                 skip "Need MDS version at least 2.2.0"
17432
17433         changelog_register || error "changelog_register failed"
17434         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17435         changelog_users $SINGLEMDS | grep -q $cl_user ||
17436                 error "User '$cl_user' not found in changelog_users"
17437
17438         local longname1=$(str_repeat a 255)
17439         local longname2=$(str_repeat b 255)
17440
17441         cd $DIR
17442         echo "creating very long named file"
17443         touch $longname1 || error "create of '$longname1' failed"
17444         echo "renaming very long named file"
17445         mv $longname1 $longname2
17446
17447         changelog_dump | grep RENME | tail -n 5
17448         rm -f $longname2
17449 }
17450 run_test 160b "Verify that very long rename doesn't crash in changelog"
17451
17452 test_160c() {
17453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17454         remote_mds_nodsh && skip "remote MDS with nodsh"
17455
17456         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17457                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17458                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17459                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17460
17461         local rc=0
17462
17463         # Registration step
17464         changelog_register || error "changelog_register failed"
17465
17466         rm -rf $DIR/$tdir
17467         mkdir -p $DIR/$tdir
17468         $MCREATE $DIR/$tdir/foo_160c
17469         changelog_chmask "-TRUNC"
17470         $TRUNCATE $DIR/$tdir/foo_160c 200
17471         changelog_chmask "+TRUNC"
17472         $TRUNCATE $DIR/$tdir/foo_160c 199
17473         changelog_dump | tail -n 5
17474         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17475         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17476 }
17477 run_test 160c "verify that changelog log catch the truncate event"
17478
17479 test_160d() {
17480         remote_mds_nodsh && skip "remote MDS with nodsh"
17481         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17483         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17484                 skip "Need MDS version at least 2.7.60"
17485
17486         # Registration step
17487         changelog_register || error "changelog_register failed"
17488
17489         mkdir -p $DIR/$tdir/migrate_dir
17490         changelog_clear 0 || error "changelog_clear failed"
17491
17492         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17493         changelog_dump | tail -n 5
17494         local migrates=$(changelog_dump | grep -c "MIGRT")
17495         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17496 }
17497 run_test 160d "verify that changelog log catch the migrate event"
17498
17499 test_160e() {
17500         remote_mds_nodsh && skip "remote MDS with nodsh"
17501
17502         # Create a user
17503         changelog_register || error "changelog_register failed"
17504
17505         local MDT0=$(facet_svc $SINGLEMDS)
17506         local rc
17507
17508         # No user (expect fail)
17509         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17510         rc=$?
17511         if [ $rc -eq 0 ]; then
17512                 error "Should fail without user"
17513         elif [ $rc -ne 4 ]; then
17514                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17515         fi
17516
17517         # Delete a future user (expect fail)
17518         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17519         rc=$?
17520         if [ $rc -eq 0 ]; then
17521                 error "Deleted non-existant user cl77"
17522         elif [ $rc -ne 2 ]; then
17523                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17524         fi
17525
17526         # Clear to a bad index (1 billion should be safe)
17527         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17528         rc=$?
17529
17530         if [ $rc -eq 0 ]; then
17531                 error "Successfully cleared to invalid CL index"
17532         elif [ $rc -ne 22 ]; then
17533                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17534         fi
17535 }
17536 run_test 160e "changelog negative testing (should return errors)"
17537
17538 test_160f() {
17539         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17540         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17541                 skip "Need MDS version at least 2.10.56"
17542
17543         local mdts=$(comma_list $(mdts_nodes))
17544
17545         # Create a user
17546         changelog_register || error "first changelog_register failed"
17547         changelog_register || error "second changelog_register failed"
17548         local cl_users
17549         declare -A cl_user1
17550         declare -A cl_user2
17551         local user_rec1
17552         local user_rec2
17553         local i
17554
17555         # generate some changelog records to accumulate on each MDT
17556         # use all_char because created files should be evenly distributed
17557         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17558                 error "test_mkdir $tdir failed"
17559         log "$(date +%s): creating first files"
17560         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17561                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17562                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17563         done
17564
17565         # check changelogs have been generated
17566         local start=$SECONDS
17567         local idle_time=$((MDSCOUNT * 5 + 5))
17568         local nbcl=$(changelog_dump | wc -l)
17569         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17570
17571         for param in "changelog_max_idle_time=$idle_time" \
17572                      "changelog_gc=1" \
17573                      "changelog_min_gc_interval=2" \
17574                      "changelog_min_free_cat_entries=3"; do
17575                 local MDT0=$(facet_svc $SINGLEMDS)
17576                 local var="${param%=*}"
17577                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17578
17579                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17580                 do_nodes $mdts $LCTL set_param mdd.*.$param
17581         done
17582
17583         # force cl_user2 to be idle (1st part), but also cancel the
17584         # cl_user1 records so that it is not evicted later in the test.
17585         local sleep1=$((idle_time / 2))
17586         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17587         sleep $sleep1
17588
17589         # simulate changelog catalog almost full
17590         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17591         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17592
17593         for i in $(seq $MDSCOUNT); do
17594                 cl_users=(${CL_USERS[mds$i]})
17595                 cl_user1[mds$i]="${cl_users[0]}"
17596                 cl_user2[mds$i]="${cl_users[1]}"
17597
17598                 [ -n "${cl_user1[mds$i]}" ] ||
17599                         error "mds$i: no user registered"
17600                 [ -n "${cl_user2[mds$i]}" ] ||
17601                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17602
17603                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17604                 [ -n "$user_rec1" ] ||
17605                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17606                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17607                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17608                 [ -n "$user_rec2" ] ||
17609                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17610                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17611                      "$user_rec1 + 2 == $user_rec2"
17612                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17613                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17614                               "$user_rec1 + 2, but is $user_rec2"
17615                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17616                 [ -n "$user_rec2" ] ||
17617                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17618                 [ $user_rec1 == $user_rec2 ] ||
17619                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17620                               "$user_rec1, but is $user_rec2"
17621         done
17622
17623         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17624         local sleep2=$((idle_time - (SECONDS - start) + 1))
17625         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17626         sleep $sleep2
17627
17628         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17629         # cl_user1 should be OK because it recently processed records.
17630         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17631         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17632                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17633                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17634         done
17635
17636         # ensure gc thread is done
17637         for i in $(mdts_nodes); do
17638                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17639                         error "$i: GC-thread not done"
17640         done
17641
17642         local first_rec
17643         for (( i = 1; i <= MDSCOUNT; i++ )); do
17644                 # check cl_user1 still registered
17645                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17646                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17647                 # check cl_user2 unregistered
17648                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17649                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17650
17651                 # check changelogs are present and starting at $user_rec1 + 1
17652                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17653                 [ -n "$user_rec1" ] ||
17654                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17655                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17656                             awk '{ print $1; exit; }')
17657
17658                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17659                 [ $((user_rec1 + 1)) == $first_rec ] ||
17660                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17661         done
17662 }
17663 run_test 160f "changelog garbage collect (timestamped users)"
17664
17665 test_160g() {
17666         remote_mds_nodsh && skip "remote MDS with nodsh"
17667         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17668                 skip "Need MDS version at least 2.14.55"
17669
17670         local mdts=$(comma_list $(mdts_nodes))
17671
17672         # Create a user
17673         changelog_register || error "first changelog_register failed"
17674         changelog_register || error "second changelog_register failed"
17675         local cl_users
17676         declare -A cl_user1
17677         declare -A cl_user2
17678         local user_rec1
17679         local user_rec2
17680         local i
17681
17682         # generate some changelog records to accumulate on each MDT
17683         # use all_char because created files should be evenly distributed
17684         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17685                 error "test_mkdir $tdir failed"
17686         for ((i = 0; i < MDSCOUNT; i++)); do
17687                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17688                         error "create $DIR/$tdir/d$i.1 failed"
17689         done
17690
17691         # check changelogs have been generated
17692         local nbcl=$(changelog_dump | wc -l)
17693         (( $nbcl > 0 )) || error "no changelogs found"
17694
17695         # reduce the max_idle_indexes value to make sure we exceed it
17696         for param in "changelog_max_idle_indexes=2" \
17697                      "changelog_gc=1" \
17698                      "changelog_min_gc_interval=2"; do
17699                 local MDT0=$(facet_svc $SINGLEMDS)
17700                 local var="${param%=*}"
17701                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17702
17703                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17704                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17705                         error "unable to set mdd.*.$param"
17706         done
17707
17708         local start=$SECONDS
17709         for i in $(seq $MDSCOUNT); do
17710                 cl_users=(${CL_USERS[mds$i]})
17711                 cl_user1[mds$i]="${cl_users[0]}"
17712                 cl_user2[mds$i]="${cl_users[1]}"
17713
17714                 [ -n "${cl_user1[mds$i]}" ] ||
17715                         error "mds$i: user1 is not registered"
17716                 [ -n "${cl_user2[mds$i]}" ] ||
17717                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17718
17719                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17720                 [ -n "$user_rec1" ] ||
17721                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17722                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17723                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17724                 [ -n "$user_rec2" ] ||
17725                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17726                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17727                      "$user_rec1 + 2 == $user_rec2"
17728                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17729                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17730                               "expected $user_rec1 + 2, but is $user_rec2"
17731                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17732                 [ -n "$user_rec2" ] ||
17733                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17734                 [ $user_rec1 == $user_rec2 ] ||
17735                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17736                               "expected $user_rec1, but is $user_rec2"
17737         done
17738
17739         # ensure we are past the previous changelog_min_gc_interval set above
17740         local sleep2=$((start + 2 - SECONDS))
17741         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17742         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17743         # cl_user1 should be OK because it recently processed records.
17744         for ((i = 0; i < MDSCOUNT; i++)); do
17745                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17746                         error "create $DIR/$tdir/d$i.3 failed"
17747         done
17748
17749         # ensure gc thread is done
17750         for i in $(mdts_nodes); do
17751                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17752                         error "$i: GC-thread not done"
17753         done
17754
17755         local first_rec
17756         for (( i = 1; i <= MDSCOUNT; i++ )); do
17757                 # check cl_user1 still registered
17758                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17759                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17760                 # check cl_user2 unregistered
17761                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17762                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17763
17764                 # check changelogs are present and starting at $user_rec1 + 1
17765                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17766                 [ -n "$user_rec1" ] ||
17767                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17768                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17769                             awk '{ print $1; exit; }')
17770
17771                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17772                 [ $((user_rec1 + 1)) == $first_rec ] ||
17773                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17774         done
17775 }
17776 run_test 160g "changelog garbage collect on idle records"
17777
17778 test_160h() {
17779         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17780         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17781                 skip "Need MDS version at least 2.10.56"
17782
17783         local mdts=$(comma_list $(mdts_nodes))
17784
17785         # Create a user
17786         changelog_register || error "first changelog_register failed"
17787         changelog_register || error "second changelog_register failed"
17788         local cl_users
17789         declare -A cl_user1
17790         declare -A cl_user2
17791         local user_rec1
17792         local user_rec2
17793         local i
17794
17795         # generate some changelog records to accumulate on each MDT
17796         # use all_char because created files should be evenly distributed
17797         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17798                 error "test_mkdir $tdir failed"
17799         for ((i = 0; i < MDSCOUNT; i++)); do
17800                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17801                         error "create $DIR/$tdir/d$i.1 failed"
17802         done
17803
17804         # check changelogs have been generated
17805         local nbcl=$(changelog_dump | wc -l)
17806         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17807
17808         for param in "changelog_max_idle_time=10" \
17809                      "changelog_gc=1" \
17810                      "changelog_min_gc_interval=2"; do
17811                 local MDT0=$(facet_svc $SINGLEMDS)
17812                 local var="${param%=*}"
17813                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17814
17815                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17816                 do_nodes $mdts $LCTL set_param mdd.*.$param
17817         done
17818
17819         # force cl_user2 to be idle (1st part)
17820         sleep 9
17821
17822         for i in $(seq $MDSCOUNT); do
17823                 cl_users=(${CL_USERS[mds$i]})
17824                 cl_user1[mds$i]="${cl_users[0]}"
17825                 cl_user2[mds$i]="${cl_users[1]}"
17826
17827                 [ -n "${cl_user1[mds$i]}" ] ||
17828                         error "mds$i: no user registered"
17829                 [ -n "${cl_user2[mds$i]}" ] ||
17830                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17831
17832                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17833                 [ -n "$user_rec1" ] ||
17834                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17835                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17836                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17837                 [ -n "$user_rec2" ] ||
17838                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17839                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17840                      "$user_rec1 + 2 == $user_rec2"
17841                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17842                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17843                               "$user_rec1 + 2, but is $user_rec2"
17844                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17845                 [ -n "$user_rec2" ] ||
17846                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17847                 [ $user_rec1 == $user_rec2 ] ||
17848                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17849                               "$user_rec1, but is $user_rec2"
17850         done
17851
17852         # force cl_user2 to be idle (2nd part) and to reach
17853         # changelog_max_idle_time
17854         sleep 2
17855
17856         # force each GC-thread start and block then
17857         # one per MDT/MDD, set fail_val accordingly
17858         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17859         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17860
17861         # generate more changelogs to trigger fail_loc
17862         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17863                 error "create $DIR/$tdir/${tfile}bis failed"
17864
17865         # stop MDT to stop GC-thread, should be done in back-ground as it will
17866         # block waiting for the thread to be released and exit
17867         declare -A stop_pids
17868         for i in $(seq $MDSCOUNT); do
17869                 stop mds$i &
17870                 stop_pids[mds$i]=$!
17871         done
17872
17873         for i in $(mdts_nodes); do
17874                 local facet
17875                 local nb=0
17876                 local facets=$(facets_up_on_host $i)
17877
17878                 for facet in ${facets//,/ }; do
17879                         if [[ $facet == mds* ]]; then
17880                                 nb=$((nb + 1))
17881                         fi
17882                 done
17883                 # ensure each MDS's gc threads are still present and all in "R"
17884                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17885                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17886                         error "$i: expected $nb GC-thread"
17887                 wait_update $i \
17888                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17889                         "R" 20 ||
17890                         error "$i: GC-thread not found in R-state"
17891                 # check umounts of each MDT on MDS have reached kthread_stop()
17892                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17893                         error "$i: expected $nb umount"
17894                 wait_update $i \
17895                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17896                         error "$i: umount not found in D-state"
17897         done
17898
17899         # release all GC-threads
17900         do_nodes $mdts $LCTL set_param fail_loc=0
17901
17902         # wait for MDT stop to complete
17903         for i in $(seq $MDSCOUNT); do
17904                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17905         done
17906
17907         # XXX
17908         # may try to check if any orphan changelog records are present
17909         # via ldiskfs/zfs and llog_reader...
17910
17911         # re-start/mount MDTs
17912         for i in $(seq $MDSCOUNT); do
17913                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17914                         error "Fail to start mds$i"
17915         done
17916
17917         local first_rec
17918         for i in $(seq $MDSCOUNT); do
17919                 # check cl_user1 still registered
17920                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17921                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17922                 # check cl_user2 unregistered
17923                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17924                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17925
17926                 # check changelogs are present and starting at $user_rec1 + 1
17927                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17928                 [ -n "$user_rec1" ] ||
17929                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17930                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17931                             awk '{ print $1; exit; }')
17932
17933                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17934                 [ $((user_rec1 + 1)) == $first_rec ] ||
17935                         error "mds$i: first index should be $user_rec1 + 1, " \
17936                               "but is $first_rec"
17937         done
17938 }
17939 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17940               "during mount"
17941
17942 test_160i() {
17943
17944         local mdts=$(comma_list $(mdts_nodes))
17945
17946         changelog_register || error "first changelog_register failed"
17947
17948         # generate some changelog records to accumulate on each MDT
17949         # use all_char because created files should be evenly distributed
17950         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17951                 error "test_mkdir $tdir failed"
17952         for ((i = 0; i < MDSCOUNT; i++)); do
17953                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17954                         error "create $DIR/$tdir/d$i.1 failed"
17955         done
17956
17957         # check changelogs have been generated
17958         local nbcl=$(changelog_dump | wc -l)
17959         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17960
17961         # simulate race between register and unregister
17962         # XXX as fail_loc is set per-MDS, with DNE configs the race
17963         # simulation will only occur for one MDT per MDS and for the
17964         # others the normal race scenario will take place
17965         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17966         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17967         do_nodes $mdts $LCTL set_param fail_val=1
17968
17969         # unregister 1st user
17970         changelog_deregister &
17971         local pid1=$!
17972         # wait some time for deregister work to reach race rdv
17973         sleep 2
17974         # register 2nd user
17975         changelog_register || error "2nd user register failed"
17976
17977         wait $pid1 || error "1st user deregister failed"
17978
17979         local i
17980         local last_rec
17981         declare -A LAST_REC
17982         for i in $(seq $MDSCOUNT); do
17983                 if changelog_users mds$i | grep "^cl"; then
17984                         # make sure new records are added with one user present
17985                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17986                                           awk '/^current.index:/ { print $NF }')
17987                 else
17988                         error "mds$i has no user registered"
17989                 fi
17990         done
17991
17992         # generate more changelog records to accumulate on each MDT
17993         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17994                 error "create $DIR/$tdir/${tfile}bis failed"
17995
17996         for i in $(seq $MDSCOUNT); do
17997                 last_rec=$(changelog_users $SINGLEMDS |
17998                            awk '/^current.index:/ { print $NF }')
17999                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18000                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18001                         error "changelogs are off on mds$i"
18002         done
18003 }
18004 run_test 160i "changelog user register/unregister race"
18005
18006 test_160j() {
18007         remote_mds_nodsh && skip "remote MDS with nodsh"
18008         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18009                 skip "Need MDS version at least 2.12.56"
18010
18011         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18012         stack_trap "umount $MOUNT2" EXIT
18013
18014         changelog_register || error "first changelog_register failed"
18015         stack_trap "changelog_deregister" EXIT
18016
18017         # generate some changelog
18018         # use all_char because created files should be evenly distributed
18019         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18020                 error "mkdir $tdir failed"
18021         for ((i = 0; i < MDSCOUNT; i++)); do
18022                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18023                         error "create $DIR/$tdir/d$i.1 failed"
18024         done
18025
18026         # open the changelog device
18027         exec 3>/dev/changelog-$FSNAME-MDT0000
18028         stack_trap "exec 3>&-" EXIT
18029         exec 4</dev/changelog-$FSNAME-MDT0000
18030         stack_trap "exec 4<&-" EXIT
18031
18032         # umount the first lustre mount
18033         umount $MOUNT
18034         stack_trap "mount_client $MOUNT" EXIT
18035
18036         # read changelog, which may or may not fail, but should not crash
18037         cat <&4 >/dev/null
18038
18039         # clear changelog
18040         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18041         changelog_users $SINGLEMDS | grep -q $cl_user ||
18042                 error "User $cl_user not found in changelog_users"
18043
18044         printf 'clear:'$cl_user':0' >&3
18045 }
18046 run_test 160j "client can be umounted while its chanangelog is being used"
18047
18048 test_160k() {
18049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18050         remote_mds_nodsh && skip "remote MDS with nodsh"
18051
18052         mkdir -p $DIR/$tdir/1/1
18053
18054         changelog_register || error "changelog_register failed"
18055         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18056
18057         changelog_users $SINGLEMDS | grep -q $cl_user ||
18058                 error "User '$cl_user' not found in changelog_users"
18059 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18060         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18061         rmdir $DIR/$tdir/1/1 & sleep 1
18062         mkdir $DIR/$tdir/2
18063         touch $DIR/$tdir/2/2
18064         rm -rf $DIR/$tdir/2
18065
18066         wait
18067         sleep 4
18068
18069         changelog_dump | grep rmdir || error "rmdir not recorded"
18070 }
18071 run_test 160k "Verify that changelog records are not lost"
18072
18073 # Verifies that a file passed as a parameter has recently had an operation
18074 # performed on it that has generated an MTIME changelog which contains the
18075 # correct parent FID. As files might reside on a different MDT from the
18076 # parent directory in DNE configurations, the FIDs are translated to paths
18077 # before being compared, which should be identical
18078 compare_mtime_changelog() {
18079         local file="${1}"
18080         local mdtidx
18081         local mtime
18082         local cl_fid
18083         local pdir
18084         local dir
18085
18086         mdtidx=$($LFS getstripe --mdt-index $file)
18087         mdtidx=$(printf "%04x" $mdtidx)
18088
18089         # Obtain the parent FID from the MTIME changelog
18090         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18091         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18092
18093         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18094         [ -z "$cl_fid" ] && error "parent FID not present"
18095
18096         # Verify that the path for the parent FID is the same as the path for
18097         # the test directory
18098         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18099
18100         dir=$(dirname $1)
18101
18102         [[ "${pdir%/}" == "$dir" ]] ||
18103                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18104 }
18105
18106 test_160l() {
18107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18108
18109         remote_mds_nodsh && skip "remote MDS with nodsh"
18110         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18111                 skip "Need MDS version at least 2.13.55"
18112
18113         local cl_user
18114
18115         changelog_register || error "changelog_register failed"
18116         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18117
18118         changelog_users $SINGLEMDS | grep -q $cl_user ||
18119                 error "User '$cl_user' not found in changelog_users"
18120
18121         # Clear some types so that MTIME changelogs are generated
18122         changelog_chmask "-CREAT"
18123         changelog_chmask "-CLOSE"
18124
18125         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18126
18127         # Test CL_MTIME during setattr
18128         touch $DIR/$tdir/$tfile
18129         compare_mtime_changelog $DIR/$tdir/$tfile
18130
18131         # Test CL_MTIME during close
18132         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18133         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18134 }
18135 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18136
18137 test_160m() {
18138         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18139         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18140                 skip "Need MDS version at least 2.14.51"
18141         local cl_users
18142         local cl_user1
18143         local cl_user2
18144         local pid1
18145
18146         # Create a user
18147         changelog_register || error "first changelog_register failed"
18148         changelog_register || error "second changelog_register failed"
18149
18150         cl_users=(${CL_USERS[mds1]})
18151         cl_user1="${cl_users[0]}"
18152         cl_user2="${cl_users[1]}"
18153         # generate some changelog records to accumulate on MDT0
18154         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18155         createmany -m $DIR/$tdir/$tfile 50 ||
18156                 error "create $DIR/$tdir/$tfile failed"
18157         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18158         rm -f $DIR/$tdir
18159
18160         # check changelogs have been generated
18161         local nbcl=$(changelog_dump | wc -l)
18162         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18163
18164 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18165         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18166
18167         __changelog_clear mds1 $cl_user1 +10
18168         __changelog_clear mds1 $cl_user2 0 &
18169         pid1=$!
18170         sleep 2
18171         __changelog_clear mds1 $cl_user1 0 ||
18172                 error "fail to cancel record for $cl_user1"
18173         wait $pid1
18174         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18175 }
18176 run_test 160m "Changelog clear race"
18177
18178 test_160n() {
18179         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18180         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18181                 skip "Need MDS version at least 2.14.51"
18182         local cl_users
18183         local cl_user1
18184         local cl_user2
18185         local pid1
18186         local first_rec
18187         local last_rec=0
18188
18189         # Create a user
18190         changelog_register || error "first changelog_register failed"
18191
18192         cl_users=(${CL_USERS[mds1]})
18193         cl_user1="${cl_users[0]}"
18194
18195         # generate some changelog records to accumulate on MDT0
18196         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18197         first_rec=$(changelog_users $SINGLEMDS |
18198                         awk '/^current.index:/ { print $NF }')
18199         while (( last_rec < (( first_rec + 65000)) )); do
18200                 createmany -m $DIR/$tdir/$tfile 10000 ||
18201                         error "create $DIR/$tdir/$tfile failed"
18202
18203                 for i in $(seq 0 10000); do
18204                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18205                                 > /dev/null
18206                 done
18207
18208                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18209                         error "unlinkmany failed unlink"
18210                 last_rec=$(changelog_users $SINGLEMDS |
18211                         awk '/^current.index:/ { print $NF }')
18212                 echo last record $last_rec
18213                 (( last_rec == 0 )) && error "no changelog found"
18214         done
18215
18216 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18217         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18218
18219         __changelog_clear mds1 $cl_user1 0 &
18220         pid1=$!
18221         sleep 2
18222         __changelog_clear mds1 $cl_user1 0 ||
18223                 error "fail to cancel record for $cl_user1"
18224         wait $pid1
18225         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18226 }
18227 run_test 160n "Changelog destroy race"
18228
18229 test_160o() {
18230         local mdt="$(facet_svc $SINGLEMDS)"
18231
18232         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18233         remote_mds_nodsh && skip "remote MDS with nodsh"
18234         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18235                 skip "Need MDS version at least 2.14.52"
18236
18237         changelog_register --user test_160o -m unlnk+close+open ||
18238                 error "changelog_register failed"
18239
18240         do_facet $SINGLEMDS $LCTL --device $mdt \
18241                                 changelog_register -u "Tt3_-#" &&
18242                 error "bad symbols in name should fail"
18243
18244         do_facet $SINGLEMDS $LCTL --device $mdt \
18245                                 changelog_register -u test_160o &&
18246                 error "the same name registration should fail"
18247
18248         do_facet $SINGLEMDS $LCTL --device $mdt \
18249                         changelog_register -u test_160toolongname &&
18250                 error "too long name registration should fail"
18251
18252         changelog_chmask "MARK+HSM"
18253         lctl get_param mdd.*.changelog*mask
18254         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18255         changelog_users $SINGLEMDS | grep -q $cl_user ||
18256                 error "User $cl_user not found in changelog_users"
18257         #verify username
18258         echo $cl_user | grep -q test_160o ||
18259                 error "User $cl_user has no specific name 'test160o'"
18260
18261         # change something
18262         changelog_clear 0 || error "changelog_clear failed"
18263         # generate some changelog records to accumulate on MDT0
18264         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18265         touch $DIR/$tdir/$tfile                 # open 1
18266
18267         OPENS=$(changelog_dump | grep -c "OPEN")
18268         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18269
18270         # must be no MKDIR it wasn't set as user mask
18271         MKDIR=$(changelog_dump | grep -c "MKDIR")
18272         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18273
18274         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18275                                 mdd.$mdt.changelog_current_mask -n)
18276         # register maskless user
18277         changelog_register || error "changelog_register failed"
18278         # effective mask should be not changed because it is not minimal
18279         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18280                                 mdd.$mdt.changelog_current_mask -n)
18281         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18282         # set server mask to minimal value
18283         changelog_chmask "MARK"
18284         # check effective mask again, should be treated as DEFMASK now
18285         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18286                                 mdd.$mdt.changelog_current_mask -n)
18287         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18288
18289         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18290                 # set server mask back to some value
18291                 changelog_chmask "CLOSE,UNLNK"
18292                 # check effective mask again, should not remain as DEFMASK
18293                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18294                                 mdd.$mdt.changelog_current_mask -n)
18295                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18296         fi
18297
18298         do_facet $SINGLEMDS $LCTL --device $mdt \
18299                                 changelog_deregister -u test_160o ||
18300                 error "cannot deregister by name"
18301 }
18302 run_test 160o "changelog user name and mask"
18303
18304 test_160p() {
18305         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18306         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18307                 skip "Need MDS version at least 2.14.51"
18308         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18309         local cl_users
18310         local cl_user1
18311         local entry_count
18312
18313         # Create a user
18314         changelog_register || error "first changelog_register failed"
18315
18316         cl_users=(${CL_USERS[mds1]})
18317         cl_user1="${cl_users[0]}"
18318
18319         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18320         createmany -m $DIR/$tdir/$tfile 50 ||
18321                 error "create $DIR/$tdir/$tfile failed"
18322         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18323         rm -rf $DIR/$tdir
18324
18325         # check changelogs have been generated
18326         entry_count=$(changelog_dump | wc -l)
18327         ((entry_count != 0)) || error "no changelog entries found"
18328
18329         # remove changelog_users and check that orphan entries are removed
18330         stop mds1
18331         local dev=$(mdsdevname 1)
18332         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18333         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18334         entry_count=$(changelog_dump | wc -l)
18335         ((entry_count == 0)) ||
18336                 error "found $entry_count changelog entries, expected none"
18337 }
18338 run_test 160p "Changelog orphan cleanup with no users"
18339
18340 test_160q() {
18341         local mdt="$(facet_svc $SINGLEMDS)"
18342         local clu
18343
18344         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18345         remote_mds_nodsh && skip "remote MDS with nodsh"
18346         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18347                 skip "Need MDS version at least 2.14.54"
18348
18349         # set server mask to minimal value like server init does
18350         changelog_chmask "MARK"
18351         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18352                 error "changelog_register failed"
18353         # check effective mask again, should be treated as DEFMASK now
18354         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18355                                 mdd.$mdt.changelog_current_mask -n)
18356         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18357                 error "changelog_deregister failed"
18358         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18359 }
18360 run_test 160q "changelog effective mask is DEFMASK if not set"
18361
18362 test_160s() {
18363         remote_mds_nodsh && skip "remote MDS with nodsh"
18364         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18365                 skip "Need MDS version at least 2.14.55"
18366
18367         local mdts=$(comma_list $(mdts_nodes))
18368
18369         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18370         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18371                                        fail_val=$((24 * 3600 * 10))
18372
18373         # Create a user which is 10 days old
18374         changelog_register || error "first changelog_register failed"
18375         local cl_users
18376         declare -A cl_user1
18377         local i
18378
18379         # generate some changelog records to accumulate on each MDT
18380         # use all_char because created files should be evenly distributed
18381         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18382                 error "test_mkdir $tdir failed"
18383         for ((i = 0; i < MDSCOUNT; i++)); do
18384                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18385                         error "create $DIR/$tdir/d$i.1 failed"
18386         done
18387
18388         # check changelogs have been generated
18389         local nbcl=$(changelog_dump | wc -l)
18390         (( nbcl > 0 )) || error "no changelogs found"
18391
18392         # reduce the max_idle_indexes value to make sure we exceed it
18393         for param in "changelog_max_idle_indexes=2097446912" \
18394                      "changelog_max_idle_time=2592000" \
18395                      "changelog_gc=1" \
18396                      "changelog_min_gc_interval=2"; do
18397                 local MDT0=$(facet_svc $SINGLEMDS)
18398                 local var="${param%=*}"
18399                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18400
18401                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18402                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18403                         error "unable to set mdd.*.$param"
18404         done
18405
18406         local start=$SECONDS
18407         for i in $(seq $MDSCOUNT); do
18408                 cl_users=(${CL_USERS[mds$i]})
18409                 cl_user1[mds$i]="${cl_users[0]}"
18410
18411                 [[ -n "${cl_user1[mds$i]}" ]] ||
18412                         error "mds$i: no user registered"
18413         done
18414
18415         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18416         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18417
18418         # ensure we are past the previous changelog_min_gc_interval set above
18419         local sleep2=$((start + 2 - SECONDS))
18420         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18421
18422         # Generate one more changelog to trigger GC
18423         for ((i = 0; i < MDSCOUNT; i++)); do
18424                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18425                         error "create $DIR/$tdir/d$i.3 failed"
18426         done
18427
18428         # ensure gc thread is done
18429         for node in $(mdts_nodes); do
18430                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18431                         error "$node: GC-thread not done"
18432         done
18433
18434         do_nodes $mdts $LCTL set_param fail_loc=0
18435
18436         for (( i = 1; i <= MDSCOUNT; i++ )); do
18437                 # check cl_user1 is purged
18438                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18439                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18440         done
18441         return 0
18442 }
18443 run_test 160s "changelog garbage collect on idle records * time"
18444
18445 test_160t() {
18446         remote_mds_nodsh && skip "remote MDS with nodsh"
18447         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18448                 skip "Need MDS version at least 2.15.50"
18449
18450         local MDT0=$(facet_svc $SINGLEMDS)
18451         local cl_users
18452         local cl_user1
18453         local cl_user2
18454         local start
18455
18456         changelog_register --user user1 -m all ||
18457                 error "user1 failed to register"
18458
18459         mkdir_on_mdt0 $DIR/$tdir
18460         # create default overstripe to maximize changelog size
18461         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18462         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18463         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18464
18465         # user2 consumes less records so less space
18466         changelog_register --user user2 || error "user2 failed to register"
18467         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18468         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18469
18470         # check changelogs have been generated
18471         local nbcl=$(changelog_dump | wc -l)
18472         (( nbcl > 0 )) || error "no changelogs found"
18473
18474         # reduce the changelog_min_gc_interval to force check
18475         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18476                 local var="${param%=*}"
18477                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18478
18479                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18480                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18481                         error "unable to set mdd.*.$param"
18482         done
18483
18484         start=$SECONDS
18485         cl_users=(${CL_USERS[mds1]})
18486         cl_user1="${cl_users[0]}"
18487         cl_user2="${cl_users[1]}"
18488
18489         [[ -n $cl_user1 ]] ||
18490                 error "mds1: user #1 isn't registered"
18491         [[ -n $cl_user2 ]] ||
18492                 error "mds1: user #2 isn't registered"
18493
18494         # ensure we are past the previous changelog_min_gc_interval set above
18495         local sleep2=$((start + 2 - SECONDS))
18496         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18497
18498         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18499         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18500                         fail_val=$(((llog_size1 + llog_size2) / 2))
18501
18502         # Generate more changelog to trigger GC
18503         createmany -o $DIR/$tdir/u3_ 4 ||
18504                 error "create failed for more files"
18505
18506         # ensure gc thread is done
18507         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18508                 error "mds1: GC-thread not done"
18509
18510         do_facet mds1 $LCTL set_param fail_loc=0
18511
18512         # check cl_user1 is purged
18513         changelog_users mds1 | grep -q "$cl_user1" &&
18514                 error "User $cl_user1 is registered"
18515         # check cl_user2 is not purged
18516         changelog_users mds1 | grep -q "$cl_user2" ||
18517                 error "User $cl_user2 is not registered"
18518 }
18519 run_test 160t "changelog garbage collect on lack of space"
18520
18521 test_161a() {
18522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18523
18524         test_mkdir -c1 $DIR/$tdir
18525         cp /etc/hosts $DIR/$tdir/$tfile
18526         test_mkdir -c1 $DIR/$tdir/foo1
18527         test_mkdir -c1 $DIR/$tdir/foo2
18528         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18529         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18530         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18531         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18532         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18533         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18534                 $LFS fid2path $DIR $FID
18535                 error "bad link ea"
18536         fi
18537         # middle
18538         rm $DIR/$tdir/foo2/zachary
18539         # last
18540         rm $DIR/$tdir/foo2/thor
18541         # first
18542         rm $DIR/$tdir/$tfile
18543         # rename
18544         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18545         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18546                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18547         rm $DIR/$tdir/foo2/maggie
18548
18549         # overflow the EA
18550         local longname=$tfile.avg_len_is_thirty_two_
18551         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18552                 error_noexit 'failed to unlink many hardlinks'" EXIT
18553         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18554                 error "failed to hardlink many files"
18555         links=$($LFS fid2path $DIR $FID | wc -l)
18556         echo -n "${links}/1000 links in link EA"
18557         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18558 }
18559 run_test 161a "link ea sanity"
18560
18561 test_161b() {
18562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18563         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18564
18565         local MDTIDX=1
18566         local remote_dir=$DIR/$tdir/remote_dir
18567
18568         mkdir -p $DIR/$tdir
18569         $LFS mkdir -i $MDTIDX $remote_dir ||
18570                 error "create remote directory failed"
18571
18572         cp /etc/hosts $remote_dir/$tfile
18573         mkdir -p $remote_dir/foo1
18574         mkdir -p $remote_dir/foo2
18575         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18576         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18577         ln $remote_dir/$tfile $remote_dir/foo1/luna
18578         ln $remote_dir/$tfile $remote_dir/foo2/thor
18579
18580         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18581                      tr -d ']')
18582         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18583                 $LFS fid2path $DIR $FID
18584                 error "bad link ea"
18585         fi
18586         # middle
18587         rm $remote_dir/foo2/zachary
18588         # last
18589         rm $remote_dir/foo2/thor
18590         # first
18591         rm $remote_dir/$tfile
18592         # rename
18593         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18594         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18595         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18596                 $LFS fid2path $DIR $FID
18597                 error "bad link rename"
18598         fi
18599         rm $remote_dir/foo2/maggie
18600
18601         # overflow the EA
18602         local longname=filename_avg_len_is_thirty_two_
18603         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18604                 error "failed to hardlink many files"
18605         links=$($LFS fid2path $DIR $FID | wc -l)
18606         echo -n "${links}/1000 links in link EA"
18607         [[ ${links} -gt 60 ]] ||
18608                 error "expected at least 60 links in link EA"
18609         unlinkmany $remote_dir/foo2/$longname 1000 ||
18610         error "failed to unlink many hardlinks"
18611 }
18612 run_test 161b "link ea sanity under remote directory"
18613
18614 test_161c() {
18615         remote_mds_nodsh && skip "remote MDS with nodsh"
18616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18617         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18618                 skip "Need MDS version at least 2.1.5"
18619
18620         # define CLF_RENAME_LAST 0x0001
18621         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18622         changelog_register || error "changelog_register failed"
18623
18624         rm -rf $DIR/$tdir
18625         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18626         touch $DIR/$tdir/foo_161c
18627         touch $DIR/$tdir/bar_161c
18628         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18629         changelog_dump | grep RENME | tail -n 5
18630         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18631         changelog_clear 0 || error "changelog_clear failed"
18632         if [ x$flags != "x0x1" ]; then
18633                 error "flag $flags is not 0x1"
18634         fi
18635
18636         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18637         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18638         touch $DIR/$tdir/foo_161c
18639         touch $DIR/$tdir/bar_161c
18640         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18641         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18642         changelog_dump | grep RENME | tail -n 5
18643         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18644         changelog_clear 0 || error "changelog_clear failed"
18645         if [ x$flags != "x0x0" ]; then
18646                 error "flag $flags is not 0x0"
18647         fi
18648         echo "rename overwrite a target having nlink > 1," \
18649                 "changelog record has flags of $flags"
18650
18651         # rename doesn't overwrite a target (changelog flag 0x0)
18652         touch $DIR/$tdir/foo_161c
18653         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18654         changelog_dump | grep RENME | tail -n 5
18655         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18656         changelog_clear 0 || error "changelog_clear failed"
18657         if [ x$flags != "x0x0" ]; then
18658                 error "flag $flags is not 0x0"
18659         fi
18660         echo "rename doesn't overwrite a target," \
18661                 "changelog record has flags of $flags"
18662
18663         # define CLF_UNLINK_LAST 0x0001
18664         # unlink a file having nlink = 1 (changelog flag 0x1)
18665         rm -f $DIR/$tdir/foo2_161c
18666         changelog_dump | grep UNLNK | tail -n 5
18667         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18668         changelog_clear 0 || error "changelog_clear failed"
18669         if [ x$flags != "x0x1" ]; then
18670                 error "flag $flags is not 0x1"
18671         fi
18672         echo "unlink a file having nlink = 1," \
18673                 "changelog record has flags of $flags"
18674
18675         # unlink a file having nlink > 1 (changelog flag 0x0)
18676         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18677         rm -f $DIR/$tdir/foobar_161c
18678         changelog_dump | grep UNLNK | tail -n 5
18679         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18680         changelog_clear 0 || error "changelog_clear failed"
18681         if [ x$flags != "x0x0" ]; then
18682                 error "flag $flags is not 0x0"
18683         fi
18684         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18685 }
18686 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18687
18688 test_161d() {
18689         remote_mds_nodsh && skip "remote MDS with nodsh"
18690         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18691
18692         local pid
18693         local fid
18694
18695         changelog_register || error "changelog_register failed"
18696
18697         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18698         # interfer with $MOUNT/.lustre/fid/ access
18699         mkdir $DIR/$tdir
18700         [[ $? -eq 0 ]] || error "mkdir failed"
18701
18702         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18703         $LCTL set_param fail_loc=0x8000140c
18704         # 5s pause
18705         $LCTL set_param fail_val=5
18706
18707         # create file
18708         echo foofoo > $DIR/$tdir/$tfile &
18709         pid=$!
18710
18711         # wait for create to be delayed
18712         sleep 2
18713
18714         ps -p $pid
18715         [[ $? -eq 0 ]] || error "create should be blocked"
18716
18717         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18718         stack_trap "rm -f $tempfile"
18719         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18720         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18721         # some delay may occur during ChangeLog publishing and file read just
18722         # above, that could allow file write to happen finally
18723         [[ -s $tempfile ]] && echo "file should be empty"
18724
18725         $LCTL set_param fail_loc=0
18726
18727         wait $pid
18728         [[ $? -eq 0 ]] || error "create failed"
18729 }
18730 run_test 161d "create with concurrent .lustre/fid access"
18731
18732 check_path() {
18733         local expected="$1"
18734         shift
18735         local fid="$2"
18736
18737         local path
18738         path=$($LFS fid2path "$@")
18739         local rc=$?
18740
18741         if [ $rc -ne 0 ]; then
18742                 error "path looked up of '$expected' failed: rc=$rc"
18743         elif [ "$path" != "$expected" ]; then
18744                 error "path looked up '$path' instead of '$expected'"
18745         else
18746                 echo "FID '$fid' resolves to path '$path' as expected"
18747         fi
18748 }
18749
18750 test_162a() { # was test_162
18751         test_mkdir -p -c1 $DIR/$tdir/d2
18752         touch $DIR/$tdir/d2/$tfile
18753         touch $DIR/$tdir/d2/x1
18754         touch $DIR/$tdir/d2/x2
18755         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18756         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18757         # regular file
18758         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18759         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18760
18761         # softlink
18762         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18763         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18764         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18765
18766         # softlink to wrong file
18767         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18768         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18769         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18770
18771         # hardlink
18772         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18773         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18774         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18775         # fid2path dir/fsname should both work
18776         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18777         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18778
18779         # hardlink count: check that there are 2 links
18780         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18781         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18782
18783         # hardlink indexing: remove the first link
18784         rm $DIR/$tdir/d2/p/q/r/hlink
18785         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18786 }
18787 run_test 162a "path lookup sanity"
18788
18789 test_162b() {
18790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18792
18793         mkdir $DIR/$tdir
18794         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18795                                 error "create striped dir failed"
18796
18797         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18798                                         tail -n 1 | awk '{print $2}')
18799         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18800
18801         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18802         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18803
18804         # regular file
18805         for ((i=0;i<5;i++)); do
18806                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18807                         error "get fid for f$i failed"
18808                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18809
18810                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18811                         error "get fid for d$i failed"
18812                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18813         done
18814
18815         return 0
18816 }
18817 run_test 162b "striped directory path lookup sanity"
18818
18819 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18820 test_162c() {
18821         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18822                 skip "Need MDS version at least 2.7.51"
18823
18824         local lpath=$tdir.local
18825         local rpath=$tdir.remote
18826
18827         test_mkdir $DIR/$lpath
18828         test_mkdir $DIR/$rpath
18829
18830         for ((i = 0; i <= 101; i++)); do
18831                 lpath="$lpath/$i"
18832                 mkdir $DIR/$lpath
18833                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18834                         error "get fid for local directory $DIR/$lpath failed"
18835                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18836
18837                 rpath="$rpath/$i"
18838                 test_mkdir $DIR/$rpath
18839                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18840                         error "get fid for remote directory $DIR/$rpath failed"
18841                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18842         done
18843
18844         return 0
18845 }
18846 run_test 162c "fid2path works with paths 100 or more directories deep"
18847
18848 oalr_event_count() {
18849         local event="${1}"
18850         local trace="${2}"
18851
18852         awk -v name="${FSNAME}-OST0000" \
18853             -v event="${event}" \
18854             '$1 == "TRACE" && $2 == event && $3 == name' \
18855             "${trace}" |
18856         wc -l
18857 }
18858
18859 oalr_expect_event_count() {
18860         local event="${1}"
18861         local trace="${2}"
18862         local expect="${3}"
18863         local count
18864
18865         count=$(oalr_event_count "${event}" "${trace}")
18866         if ((count == expect)); then
18867                 return 0
18868         fi
18869
18870         error_noexit "${event} event count was '${count}', expected ${expect}"
18871         cat "${trace}" >&2
18872         exit 1
18873 }
18874
18875 cleanup_165() {
18876         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18877         stop ost1
18878         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18879 }
18880
18881 setup_165() {
18882         sync # Flush previous IOs so we can count log entries.
18883         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18884         stack_trap cleanup_165 EXIT
18885 }
18886
18887 test_165a() {
18888         local trace="/tmp/${tfile}.trace"
18889         local rc
18890         local count
18891
18892         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18893                 skip "OFD access log unsupported"
18894
18895         setup_165
18896         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18897         sleep 5
18898
18899         do_facet ost1 ofd_access_log_reader --list
18900         stop ost1
18901
18902         do_facet ost1 killall -TERM ofd_access_log_reader
18903         wait
18904         rc=$?
18905
18906         if ((rc != 0)); then
18907                 error "ofd_access_log_reader exited with rc = '${rc}'"
18908         fi
18909
18910         # Parse trace file for discovery events:
18911         oalr_expect_event_count alr_log_add "${trace}" 1
18912         oalr_expect_event_count alr_log_eof "${trace}" 1
18913         oalr_expect_event_count alr_log_free "${trace}" 1
18914 }
18915 run_test 165a "ofd access log discovery"
18916
18917 test_165b() {
18918         local trace="/tmp/${tfile}.trace"
18919         local file="${DIR}/${tfile}"
18920         local pfid1
18921         local pfid2
18922         local -a entry
18923         local rc
18924         local count
18925         local size
18926         local flags
18927
18928         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18929                 skip "OFD access log unsupported"
18930
18931         setup_165
18932         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18933         sleep 5
18934
18935         do_facet ost1 ofd_access_log_reader --list
18936
18937         lfs setstripe -c 1 -i 0 "${file}"
18938         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18939                 error "cannot create '${file}'"
18940
18941         sleep 5
18942         do_facet ost1 killall -TERM ofd_access_log_reader
18943         wait
18944         rc=$?
18945
18946         if ((rc != 0)); then
18947                 error "ofd_access_log_reader exited with rc = '${rc}'"
18948         fi
18949
18950         oalr_expect_event_count alr_log_entry "${trace}" 1
18951
18952         pfid1=$($LFS path2fid "${file}")
18953
18954         # 1     2             3   4    5     6   7    8    9     10
18955         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18956         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18957
18958         echo "entry = '${entry[*]}'" >&2
18959
18960         pfid2=${entry[4]}
18961         if [[ "${pfid1}" != "${pfid2}" ]]; then
18962                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18963         fi
18964
18965         size=${entry[8]}
18966         if ((size != 1048576)); then
18967                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18968         fi
18969
18970         flags=${entry[10]}
18971         if [[ "${flags}" != "w" ]]; then
18972                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18973         fi
18974
18975         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18976         sleep 5
18977
18978         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18979                 error "cannot read '${file}'"
18980         sleep 5
18981
18982         do_facet ost1 killall -TERM ofd_access_log_reader
18983         wait
18984         rc=$?
18985
18986         if ((rc != 0)); then
18987                 error "ofd_access_log_reader exited with rc = '${rc}'"
18988         fi
18989
18990         oalr_expect_event_count alr_log_entry "${trace}" 1
18991
18992         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18993         echo "entry = '${entry[*]}'" >&2
18994
18995         pfid2=${entry[4]}
18996         if [[ "${pfid1}" != "${pfid2}" ]]; then
18997                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18998         fi
18999
19000         size=${entry[8]}
19001         if ((size != 524288)); then
19002                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19003         fi
19004
19005         flags=${entry[10]}
19006         if [[ "${flags}" != "r" ]]; then
19007                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19008         fi
19009 }
19010 run_test 165b "ofd access log entries are produced and consumed"
19011
19012 test_165c() {
19013         local trace="/tmp/${tfile}.trace"
19014         local file="${DIR}/${tdir}/${tfile}"
19015
19016         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19017                 skip "OFD access log unsupported"
19018
19019         test_mkdir "${DIR}/${tdir}"
19020
19021         setup_165
19022         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19023         sleep 5
19024
19025         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19026
19027         # 4096 / 64 = 64. Create twice as many entries.
19028         for ((i = 0; i < 128; i++)); do
19029                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19030                         error "cannot create file"
19031         done
19032
19033         sync
19034
19035         do_facet ost1 killall -TERM ofd_access_log_reader
19036         wait
19037         rc=$?
19038         if ((rc != 0)); then
19039                 error "ofd_access_log_reader exited with rc = '${rc}'"
19040         fi
19041
19042         unlinkmany  "${file}-%d" 128
19043 }
19044 run_test 165c "full ofd access logs do not block IOs"
19045
19046 oal_get_read_count() {
19047         local stats="$1"
19048
19049         # STATS lustre-OST0001 alr_read_count 1
19050
19051         do_facet ost1 cat "${stats}" |
19052         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19053              END { print count; }'
19054 }
19055
19056 oal_expect_read_count() {
19057         local stats="$1"
19058         local count
19059         local expect="$2"
19060
19061         # Ask ofd_access_log_reader to write stats.
19062         do_facet ost1 killall -USR1 ofd_access_log_reader
19063
19064         # Allow some time for things to happen.
19065         sleep 1
19066
19067         count=$(oal_get_read_count "${stats}")
19068         if ((count == expect)); then
19069                 return 0
19070         fi
19071
19072         error_noexit "bad read count, got ${count}, expected ${expect}"
19073         do_facet ost1 cat "${stats}" >&2
19074         exit 1
19075 }
19076
19077 test_165d() {
19078         local stats="/tmp/${tfile}.stats"
19079         local file="${DIR}/${tdir}/${tfile}"
19080         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19081
19082         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19083                 skip "OFD access log unsupported"
19084
19085         test_mkdir "${DIR}/${tdir}"
19086
19087         setup_165
19088         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19089         sleep 5
19090
19091         lfs setstripe -c 1 -i 0 "${file}"
19092
19093         do_facet ost1 lctl set_param "${param}=rw"
19094         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19095                 error "cannot create '${file}'"
19096         oal_expect_read_count "${stats}" 1
19097
19098         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19099                 error "cannot read '${file}'"
19100         oal_expect_read_count "${stats}" 2
19101
19102         do_facet ost1 lctl set_param "${param}=r"
19103         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19104                 error "cannot create '${file}'"
19105         oal_expect_read_count "${stats}" 2
19106
19107         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19108                 error "cannot read '${file}'"
19109         oal_expect_read_count "${stats}" 3
19110
19111         do_facet ost1 lctl set_param "${param}=w"
19112         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19113                 error "cannot create '${file}'"
19114         oal_expect_read_count "${stats}" 4
19115
19116         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19117                 error "cannot read '${file}'"
19118         oal_expect_read_count "${stats}" 4
19119
19120         do_facet ost1 lctl set_param "${param}=0"
19121         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19122                 error "cannot create '${file}'"
19123         oal_expect_read_count "${stats}" 4
19124
19125         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19126                 error "cannot read '${file}'"
19127         oal_expect_read_count "${stats}" 4
19128
19129         do_facet ost1 killall -TERM ofd_access_log_reader
19130         wait
19131         rc=$?
19132         if ((rc != 0)); then
19133                 error "ofd_access_log_reader exited with rc = '${rc}'"
19134         fi
19135 }
19136 run_test 165d "ofd_access_log mask works"
19137
19138 test_165e() {
19139         local stats="/tmp/${tfile}.stats"
19140         local file0="${DIR}/${tdir}-0/${tfile}"
19141         local file1="${DIR}/${tdir}-1/${tfile}"
19142
19143         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19144                 skip "OFD access log unsupported"
19145
19146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19147
19148         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19149         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19150
19151         lfs setstripe -c 1 -i 0 "${file0}"
19152         lfs setstripe -c 1 -i 0 "${file1}"
19153
19154         setup_165
19155         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19156         sleep 5
19157
19158         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19159                 error "cannot create '${file0}'"
19160         sync
19161         oal_expect_read_count "${stats}" 0
19162
19163         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19164                 error "cannot create '${file1}'"
19165         sync
19166         oal_expect_read_count "${stats}" 1
19167
19168         do_facet ost1 killall -TERM ofd_access_log_reader
19169         wait
19170         rc=$?
19171         if ((rc != 0)); then
19172                 error "ofd_access_log_reader exited with rc = '${rc}'"
19173         fi
19174 }
19175 run_test 165e "ofd_access_log MDT index filter works"
19176
19177 test_165f() {
19178         local trace="/tmp/${tfile}.trace"
19179         local rc
19180         local count
19181
19182         setup_165
19183         do_facet ost1 timeout 60 ofd_access_log_reader \
19184                 --exit-on-close --debug=- --trace=- > "${trace}" &
19185         sleep 5
19186         stop ost1
19187
19188         wait
19189         rc=$?
19190
19191         if ((rc != 0)); then
19192                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19193                 cat "${trace}"
19194                 exit 1
19195         fi
19196 }
19197 run_test 165f "ofd_access_log_reader --exit-on-close works"
19198
19199 test_169() {
19200         # do directio so as not to populate the page cache
19201         log "creating a 10 Mb file"
19202         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19203                 error "multiop failed while creating a file"
19204         log "starting reads"
19205         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19206         log "truncating the file"
19207         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19208                 error "multiop failed while truncating the file"
19209         log "killing dd"
19210         kill %+ || true # reads might have finished
19211         echo "wait until dd is finished"
19212         wait
19213         log "removing the temporary file"
19214         rm -rf $DIR/$tfile || error "tmp file removal failed"
19215 }
19216 run_test 169 "parallel read and truncate should not deadlock"
19217
19218 test_170() {
19219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19220
19221         $LCTL clear     # bug 18514
19222         $LCTL debug_daemon start $TMP/${tfile}_log_good
19223         touch $DIR/$tfile
19224         $LCTL debug_daemon stop
19225         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19226                 error "sed failed to read log_good"
19227
19228         $LCTL debug_daemon start $TMP/${tfile}_log_good
19229         rm -rf $DIR/$tfile
19230         $LCTL debug_daemon stop
19231
19232         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19233                error "lctl df log_bad failed"
19234
19235         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19236         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19237
19238         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19239         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19240
19241         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19242                 error "bad_line good_line1 good_line2 are empty"
19243
19244         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19245         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19246         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19247
19248         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19249         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19250         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19251
19252         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19253                 error "bad_line_new good_line_new are empty"
19254
19255         local expected_good=$((good_line1 + good_line2*2))
19256
19257         rm -f $TMP/${tfile}*
19258         # LU-231, short malformed line may not be counted into bad lines
19259         if [ $bad_line -ne $bad_line_new ] &&
19260                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19261                 error "expected $bad_line bad lines, but got $bad_line_new"
19262                 return 1
19263         fi
19264
19265         if [ $expected_good -ne $good_line_new ]; then
19266                 error "expected $expected_good good lines, but got $good_line_new"
19267                 return 2
19268         fi
19269         true
19270 }
19271 run_test 170 "test lctl df to handle corrupted log ====================="
19272
19273 test_171() { # bug20592
19274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19275
19276         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19277         $LCTL set_param fail_loc=0x50e
19278         $LCTL set_param fail_val=3000
19279         multiop_bg_pause $DIR/$tfile O_s || true
19280         local MULTIPID=$!
19281         kill -USR1 $MULTIPID
19282         # cause log dump
19283         sleep 3
19284         wait $MULTIPID
19285         if dmesg | grep "recursive fault"; then
19286                 error "caught a recursive fault"
19287         fi
19288         $LCTL set_param fail_loc=0
19289         true
19290 }
19291 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19292
19293 test_172() {
19294
19295         #define OBD_FAIL_OBD_CLEANUP  0x60e
19296         $LCTL set_param fail_loc=0x60e
19297         umount $MOUNT || error "umount $MOUNT failed"
19298         stack_trap "mount_client $MOUNT"
19299
19300         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19301                 error "no client OBDs are remained"
19302
19303         $LCTL dl | while read devno state type name foo; do
19304                 case $type in
19305                 lov|osc|lmv|mdc)
19306                         $LCTL --device $name cleanup
19307                         $LCTL --device $name detach
19308                         ;;
19309                 *)
19310                         # skip server devices
19311                         ;;
19312                 esac
19313         done
19314
19315         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19316                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19317                 error "some client OBDs are still remained"
19318         fi
19319
19320 }
19321 run_test 172 "manual device removal with lctl cleanup/detach ======"
19322
19323 # it would be good to share it with obdfilter-survey/iokit-libecho code
19324 setup_obdecho_osc () {
19325         local rc=0
19326         local ost_nid=$1
19327         local obdfilter_name=$2
19328         echo "Creating new osc for $obdfilter_name on $ost_nid"
19329         # make sure we can find loopback nid
19330         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19331
19332         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19333                            ${obdfilter_name}_osc_UUID || rc=2; }
19334         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19335                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19336         return $rc
19337 }
19338
19339 cleanup_obdecho_osc () {
19340         local obdfilter_name=$1
19341         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19342         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19343         return 0
19344 }
19345
19346 obdecho_test() {
19347         local OBD=$1
19348         local node=$2
19349         local pages=${3:-64}
19350         local rc=0
19351         local id
19352
19353         local count=10
19354         local obd_size=$(get_obd_size $node $OBD)
19355         local page_size=$(get_page_size $node)
19356         if [[ -n "$obd_size" ]]; then
19357                 local new_count=$((obd_size / (pages * page_size / 1024)))
19358                 [[ $new_count -ge $count ]] || count=$new_count
19359         fi
19360
19361         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19362         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19363                            rc=2; }
19364         if [ $rc -eq 0 ]; then
19365             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19366             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19367         fi
19368         echo "New object id is $id"
19369         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19370                            rc=4; }
19371         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19372                            "test_brw $count w v $pages $id" || rc=4; }
19373         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19374                            rc=4; }
19375         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19376                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19377         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19378                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19379         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19380         return $rc
19381 }
19382
19383 test_180a() {
19384         skip "obdecho on osc is no longer supported"
19385 }
19386 run_test 180a "test obdecho on osc"
19387
19388 test_180b() {
19389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19390         remote_ost_nodsh && skip "remote OST with nodsh"
19391
19392         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19393                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19394                 error "failed to load module obdecho"
19395
19396         local target=$(do_facet ost1 $LCTL dl |
19397                        awk '/obdfilter/ { print $4; exit; }')
19398
19399         if [ -n "$target" ]; then
19400                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19401         else
19402                 do_facet ost1 $LCTL dl
19403                 error "there is no obdfilter target on ost1"
19404         fi
19405 }
19406 run_test 180b "test obdecho directly on obdfilter"
19407
19408 test_180c() { # LU-2598
19409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19410         remote_ost_nodsh && skip "remote OST with nodsh"
19411         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19412                 skip "Need MDS version at least 2.4.0"
19413
19414         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19415                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19416                 error "failed to load module obdecho"
19417
19418         local target=$(do_facet ost1 $LCTL dl |
19419                        awk '/obdfilter/ { print $4; exit; }')
19420
19421         if [ -n "$target" ]; then
19422                 local pages=16384 # 64MB bulk I/O RPC size
19423
19424                 obdecho_test "$target" ost1 "$pages" ||
19425                         error "obdecho_test with pages=$pages failed with $?"
19426         else
19427                 do_facet ost1 $LCTL dl
19428                 error "there is no obdfilter target on ost1"
19429         fi
19430 }
19431 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19432
19433 test_181() { # bug 22177
19434         test_mkdir $DIR/$tdir
19435         # create enough files to index the directory
19436         createmany -o $DIR/$tdir/foobar 4000
19437         # print attributes for debug purpose
19438         lsattr -d .
19439         # open dir
19440         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19441         MULTIPID=$!
19442         # remove the files & current working dir
19443         unlinkmany $DIR/$tdir/foobar 4000
19444         rmdir $DIR/$tdir
19445         kill -USR1 $MULTIPID
19446         wait $MULTIPID
19447         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19448         return 0
19449 }
19450 run_test 181 "Test open-unlinked dir ========================"
19451
19452 test_182a() {
19453         local fcount=1000
19454         local tcount=10
19455
19456         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19457
19458         $LCTL set_param mdc.*.rpc_stats=clear
19459
19460         for (( i = 0; i < $tcount; i++ )) ; do
19461                 mkdir $DIR/$tdir/$i
19462         done
19463
19464         for (( i = 0; i < $tcount; i++ )) ; do
19465                 createmany -o $DIR/$tdir/$i/f- $fcount &
19466         done
19467         wait
19468
19469         for (( i = 0; i < $tcount; i++ )) ; do
19470                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19471         done
19472         wait
19473
19474         $LCTL get_param mdc.*.rpc_stats
19475
19476         rm -rf $DIR/$tdir
19477 }
19478 run_test 182a "Test parallel modify metadata operations from mdc"
19479
19480 test_182b() {
19481         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19482         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19483         local dcount=1000
19484         local tcount=10
19485         local stime
19486         local etime
19487         local delta
19488
19489         do_facet mds1 $LCTL list_param \
19490                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19491                 skip "MDS lacks parallel RPC handling"
19492
19493         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19494
19495         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19496                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19497
19498         stime=$(date +%s)
19499         createmany -i 0 -d $DIR/$tdir/t- $tcount
19500
19501         for (( i = 0; i < $tcount; i++ )) ; do
19502                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19503         done
19504         wait
19505         etime=$(date +%s)
19506         delta=$((etime - stime))
19507         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19508
19509         stime=$(date +%s)
19510         for (( i = 0; i < $tcount; i++ )) ; do
19511                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19512         done
19513         wait
19514         etime=$(date +%s)
19515         delta=$((etime - stime))
19516         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19517
19518         rm -rf $DIR/$tdir
19519
19520         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19521
19522         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19523
19524         stime=$(date +%s)
19525         createmany -i 0 -d $DIR/$tdir/t- $tcount
19526
19527         for (( i = 0; i < $tcount; i++ )) ; do
19528                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19529         done
19530         wait
19531         etime=$(date +%s)
19532         delta=$((etime - stime))
19533         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19534
19535         stime=$(date +%s)
19536         for (( i = 0; i < $tcount; i++ )) ; do
19537                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19538         done
19539         wait
19540         etime=$(date +%s)
19541         delta=$((etime - stime))
19542         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19543
19544         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19545 }
19546 run_test 182b "Test parallel modify metadata operations from osp"
19547
19548 test_183() { # LU-2275
19549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19550         remote_mds_nodsh && skip "remote MDS with nodsh"
19551         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19552                 skip "Need MDS version at least 2.3.56"
19553
19554         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19555         echo aaa > $DIR/$tdir/$tfile
19556
19557 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19558         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19559
19560         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19561         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19562
19563         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19564
19565         # Flush negative dentry cache
19566         touch $DIR/$tdir/$tfile
19567
19568         # We are not checking for any leaked references here, they'll
19569         # become evident next time we do cleanup with module unload.
19570         rm -rf $DIR/$tdir
19571 }
19572 run_test 183 "No crash or request leak in case of strange dispositions ========"
19573
19574 # test suite 184 is for LU-2016, LU-2017
19575 test_184a() {
19576         check_swap_layouts_support
19577
19578         dir0=$DIR/$tdir/$testnum
19579         test_mkdir -p -c1 $dir0
19580         ref1=/etc/passwd
19581         ref2=/etc/group
19582         file1=$dir0/f1
19583         file2=$dir0/f2
19584         $LFS setstripe -c1 $file1
19585         cp $ref1 $file1
19586         $LFS setstripe -c2 $file2
19587         cp $ref2 $file2
19588         gen1=$($LFS getstripe -g $file1)
19589         gen2=$($LFS getstripe -g $file2)
19590
19591         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19592         gen=$($LFS getstripe -g $file1)
19593         [[ $gen1 != $gen ]] ||
19594                 error "Layout generation on $file1 does not change"
19595         gen=$($LFS getstripe -g $file2)
19596         [[ $gen2 != $gen ]] ||
19597                 error "Layout generation on $file2 does not change"
19598
19599         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19600         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19601
19602         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19603 }
19604 run_test 184a "Basic layout swap"
19605
19606 test_184b() {
19607         check_swap_layouts_support
19608
19609         dir0=$DIR/$tdir/$testnum
19610         mkdir -p $dir0 || error "creating dir $dir0"
19611         file1=$dir0/f1
19612         file2=$dir0/f2
19613         file3=$dir0/f3
19614         dir1=$dir0/d1
19615         dir2=$dir0/d2
19616         mkdir $dir1 $dir2
19617         $LFS setstripe -c1 $file1
19618         $LFS setstripe -c2 $file2
19619         $LFS setstripe -c1 $file3
19620         chown $RUNAS_ID $file3
19621         gen1=$($LFS getstripe -g $file1)
19622         gen2=$($LFS getstripe -g $file2)
19623
19624         $LFS swap_layouts $dir1 $dir2 &&
19625                 error "swap of directories layouts should fail"
19626         $LFS swap_layouts $dir1 $file1 &&
19627                 error "swap of directory and file layouts should fail"
19628         $RUNAS $LFS swap_layouts $file1 $file2 &&
19629                 error "swap of file we cannot write should fail"
19630         $LFS swap_layouts $file1 $file3 &&
19631                 error "swap of file with different owner should fail"
19632         /bin/true # to clear error code
19633 }
19634 run_test 184b "Forbidden layout swap (will generate errors)"
19635
19636 test_184c() {
19637         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19638         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19639         check_swap_layouts_support
19640         check_swap_layout_no_dom $DIR
19641
19642         local dir0=$DIR/$tdir/$testnum
19643         mkdir -p $dir0 || error "creating dir $dir0"
19644
19645         local ref1=$dir0/ref1
19646         local ref2=$dir0/ref2
19647         local file1=$dir0/file1
19648         local file2=$dir0/file2
19649         # create a file large enough for the concurrent test
19650         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19651         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19652         echo "ref file size: ref1($(stat -c %s $ref1))," \
19653              "ref2($(stat -c %s $ref2))"
19654
19655         cp $ref2 $file2
19656         dd if=$ref1 of=$file1 bs=16k &
19657         local DD_PID=$!
19658
19659         # Make sure dd starts to copy file, but wait at most 5 seconds
19660         local loops=0
19661         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19662
19663         $LFS swap_layouts $file1 $file2
19664         local rc=$?
19665         wait $DD_PID
19666         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19667         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19668
19669         # how many bytes copied before swapping layout
19670         local copied=$(stat -c %s $file2)
19671         local remaining=$(stat -c %s $ref1)
19672         remaining=$((remaining - copied))
19673         echo "Copied $copied bytes before swapping layout..."
19674
19675         cmp -n $copied $file1 $ref2 | grep differ &&
19676                 error "Content mismatch [0, $copied) of ref2 and file1"
19677         cmp -n $copied $file2 $ref1 ||
19678                 error "Content mismatch [0, $copied) of ref1 and file2"
19679         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19680                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19681
19682         # clean up
19683         rm -f $ref1 $ref2 $file1 $file2
19684 }
19685 run_test 184c "Concurrent write and layout swap"
19686
19687 test_184d() {
19688         check_swap_layouts_support
19689         check_swap_layout_no_dom $DIR
19690         [ -z "$(which getfattr 2>/dev/null)" ] &&
19691                 skip_env "no getfattr command"
19692
19693         local file1=$DIR/$tdir/$tfile-1
19694         local file2=$DIR/$tdir/$tfile-2
19695         local file3=$DIR/$tdir/$tfile-3
19696         local lovea1
19697         local lovea2
19698
19699         mkdir -p $DIR/$tdir
19700         touch $file1 || error "create $file1 failed"
19701         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19702                 error "create $file2 failed"
19703         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19704                 error "create $file3 failed"
19705         lovea1=$(get_layout_param $file1)
19706
19707         $LFS swap_layouts $file2 $file3 ||
19708                 error "swap $file2 $file3 layouts failed"
19709         $LFS swap_layouts $file1 $file2 ||
19710                 error "swap $file1 $file2 layouts failed"
19711
19712         lovea2=$(get_layout_param $file2)
19713         echo "$lovea1"
19714         echo "$lovea2"
19715         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19716
19717         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19718         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19719 }
19720 run_test 184d "allow stripeless layouts swap"
19721
19722 test_184e() {
19723         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19724                 skip "Need MDS version at least 2.6.94"
19725         check_swap_layouts_support
19726         check_swap_layout_no_dom $DIR
19727         [ -z "$(which getfattr 2>/dev/null)" ] &&
19728                 skip_env "no getfattr command"
19729
19730         local file1=$DIR/$tdir/$tfile-1
19731         local file2=$DIR/$tdir/$tfile-2
19732         local file3=$DIR/$tdir/$tfile-3
19733         local lovea
19734
19735         mkdir -p $DIR/$tdir
19736         touch $file1 || error "create $file1 failed"
19737         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19738                 error "create $file2 failed"
19739         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19740                 error "create $file3 failed"
19741
19742         $LFS swap_layouts $file1 $file2 ||
19743                 error "swap $file1 $file2 layouts failed"
19744
19745         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19746         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19747
19748         echo 123 > $file1 || error "Should be able to write into $file1"
19749
19750         $LFS swap_layouts $file1 $file3 ||
19751                 error "swap $file1 $file3 layouts failed"
19752
19753         echo 123 > $file1 || error "Should be able to write into $file1"
19754
19755         rm -rf $file1 $file2 $file3
19756 }
19757 run_test 184e "Recreate layout after stripeless layout swaps"
19758
19759 test_184f() {
19760         # Create a file with name longer than sizeof(struct stat) ==
19761         # 144 to see if we can get chars from the file name to appear
19762         # in the returned striping. Note that 'f' == 0x66.
19763         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19764
19765         mkdir -p $DIR/$tdir
19766         mcreate $DIR/$tdir/$file
19767         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19768                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19769         fi
19770 }
19771 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19772
19773 test_185() { # LU-2441
19774         # LU-3553 - no volatile file support in old servers
19775         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19776                 skip "Need MDS version at least 2.3.60"
19777
19778         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19779         touch $DIR/$tdir/spoo
19780         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19781         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19782                 error "cannot create/write a volatile file"
19783         [ "$FILESET" == "" ] &&
19784         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19785                 error "FID is still valid after close"
19786
19787         multiop_bg_pause $DIR/$tdir Vw4096_c
19788         local multi_pid=$!
19789
19790         local OLD_IFS=$IFS
19791         IFS=":"
19792         local fidv=($fid)
19793         IFS=$OLD_IFS
19794         # assume that the next FID for this client is sequential, since stdout
19795         # is unfortunately eaten by multiop_bg_pause
19796         local n=$((${fidv[1]} + 1))
19797         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19798         if [ "$FILESET" == "" ]; then
19799                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19800                         error "FID is missing before close"
19801         fi
19802         kill -USR1 $multi_pid
19803         # 1 second delay, so if mtime change we will see it
19804         sleep 1
19805         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19806         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19807 }
19808 run_test 185 "Volatile file support"
19809
19810 function create_check_volatile() {
19811         local idx=$1
19812         local tgt
19813
19814         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19815         local PID=$!
19816         sleep 1
19817         local FID=$(cat /tmp/${tfile}.fid)
19818         [ "$FID" == "" ] && error "can't get FID for volatile"
19819         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19820         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19821         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19822         kill -USR1 $PID
19823         wait
19824         sleep 1
19825         cancel_lru_locks mdc # flush opencache
19826         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19827         return 0
19828 }
19829
19830 test_185a(){
19831         # LU-12516 - volatile creation via .lustre
19832         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19833                 skip "Need MDS version at least 2.3.55"
19834
19835         create_check_volatile 0
19836         [ $MDSCOUNT -lt 2 ] && return 0
19837
19838         # DNE case
19839         create_check_volatile 1
19840
19841         return 0
19842 }
19843 run_test 185a "Volatile file creation in .lustre/fid/"
19844
19845 test_187a() {
19846         remote_mds_nodsh && skip "remote MDS with nodsh"
19847         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19848                 skip "Need MDS version at least 2.3.0"
19849
19850         local dir0=$DIR/$tdir/$testnum
19851         mkdir -p $dir0 || error "creating dir $dir0"
19852
19853         local file=$dir0/file1
19854         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19855         stack_trap "rm -f $file"
19856         local dv1=$($LFS data_version $file)
19857         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19858         local dv2=$($LFS data_version $file)
19859         [[ $dv1 != $dv2 ]] ||
19860                 error "data version did not change on write $dv1 == $dv2"
19861 }
19862 run_test 187a "Test data version change"
19863
19864 test_187b() {
19865         remote_mds_nodsh && skip "remote MDS with nodsh"
19866         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19867                 skip "Need MDS version at least 2.3.0"
19868
19869         local dir0=$DIR/$tdir/$testnum
19870         mkdir -p $dir0 || error "creating dir $dir0"
19871
19872         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19873         [[ ${DV[0]} != ${DV[1]} ]] ||
19874                 error "data version did not change on write"\
19875                       " ${DV[0]} == ${DV[1]}"
19876
19877         # clean up
19878         rm -f $file1
19879 }
19880 run_test 187b "Test data version change on volatile file"
19881
19882 test_200() {
19883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19884         remote_mgs_nodsh && skip "remote MGS with nodsh"
19885         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19886
19887         local POOL=${POOL:-cea1}
19888         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19889         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19890         # Pool OST targets
19891         local first_ost=0
19892         local last_ost=$(($OSTCOUNT - 1))
19893         local ost_step=2
19894         local ost_list=$(seq $first_ost $ost_step $last_ost)
19895         local ost_range="$first_ost $last_ost $ost_step"
19896         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19897         local file_dir=$POOL_ROOT/file_tst
19898         local subdir=$test_path/subdir
19899         local rc=0
19900
19901         while : ; do
19902                 # former test_200a test_200b
19903                 pool_add $POOL                          || { rc=$? ; break; }
19904                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19905                 # former test_200c test_200d
19906                 mkdir -p $test_path
19907                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19908                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19909                 mkdir -p $subdir
19910                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19911                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19912                                                         || { rc=$? ; break; }
19913                 # former test_200e test_200f
19914                 local files=$((OSTCOUNT*3))
19915                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19916                                                         || { rc=$? ; break; }
19917                 pool_create_files $POOL $file_dir $files "$ost_list" \
19918                                                         || { rc=$? ; break; }
19919                 # former test_200g test_200h
19920                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19921                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19922
19923                 # former test_201a test_201b test_201c
19924                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19925
19926                 local f=$test_path/$tfile
19927                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19928                 pool_remove $POOL $f                    || { rc=$? ; break; }
19929                 break
19930         done
19931
19932         destroy_test_pools
19933
19934         return $rc
19935 }
19936 run_test 200 "OST pools"
19937
19938 # usage: default_attr <count | size | offset>
19939 default_attr() {
19940         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19941 }
19942
19943 # usage: check_default_stripe_attr
19944 check_default_stripe_attr() {
19945         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19946         case $1 in
19947         --stripe-count|-c)
19948                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19949         --stripe-size|-S)
19950                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19951         --stripe-index|-i)
19952                 EXPECTED=-1;;
19953         *)
19954                 error "unknown getstripe attr '$1'"
19955         esac
19956
19957         [ $ACTUAL == $EXPECTED ] ||
19958                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19959 }
19960
19961 test_204a() {
19962         test_mkdir $DIR/$tdir
19963         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19964
19965         check_default_stripe_attr --stripe-count
19966         check_default_stripe_attr --stripe-size
19967         check_default_stripe_attr --stripe-index
19968 }
19969 run_test 204a "Print default stripe attributes"
19970
19971 test_204b() {
19972         test_mkdir $DIR/$tdir
19973         $LFS setstripe --stripe-count 1 $DIR/$tdir
19974
19975         check_default_stripe_attr --stripe-size
19976         check_default_stripe_attr --stripe-index
19977 }
19978 run_test 204b "Print default stripe size and offset"
19979
19980 test_204c() {
19981         test_mkdir $DIR/$tdir
19982         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19983
19984         check_default_stripe_attr --stripe-count
19985         check_default_stripe_attr --stripe-index
19986 }
19987 run_test 204c "Print default stripe count and offset"
19988
19989 test_204d() {
19990         test_mkdir $DIR/$tdir
19991         $LFS setstripe --stripe-index 0 $DIR/$tdir
19992
19993         check_default_stripe_attr --stripe-count
19994         check_default_stripe_attr --stripe-size
19995 }
19996 run_test 204d "Print default stripe count and size"
19997
19998 test_204e() {
19999         test_mkdir $DIR/$tdir
20000         $LFS setstripe -d $DIR/$tdir
20001
20002         # LU-16904 check if root is set as PFL layout
20003         local numcomp=$($LFS getstripe --component-count $MOUNT)
20004
20005         if [[ $numcomp -gt 0 ]]; then
20006                 check_default_stripe_attr --stripe-count
20007         else
20008                 check_default_stripe_attr --stripe-count --raw
20009         fi
20010         check_default_stripe_attr --stripe-size --raw
20011         check_default_stripe_attr --stripe-index --raw
20012 }
20013 run_test 204e "Print raw stripe attributes"
20014
20015 test_204f() {
20016         test_mkdir $DIR/$tdir
20017         $LFS setstripe --stripe-count 1 $DIR/$tdir
20018
20019         check_default_stripe_attr --stripe-size --raw
20020         check_default_stripe_attr --stripe-index --raw
20021 }
20022 run_test 204f "Print raw stripe size and offset"
20023
20024 test_204g() {
20025         test_mkdir $DIR/$tdir
20026         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20027
20028         check_default_stripe_attr --stripe-count --raw
20029         check_default_stripe_attr --stripe-index --raw
20030 }
20031 run_test 204g "Print raw stripe count and offset"
20032
20033 test_204h() {
20034         test_mkdir $DIR/$tdir
20035         $LFS setstripe --stripe-index 0 $DIR/$tdir
20036
20037         check_default_stripe_attr --stripe-count --raw
20038         check_default_stripe_attr --stripe-size --raw
20039 }
20040 run_test 204h "Print raw stripe count and size"
20041
20042 # Figure out which job scheduler is being used, if any,
20043 # or use a fake one
20044 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20045         JOBENV=SLURM_JOB_ID
20046 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20047         JOBENV=LSB_JOBID
20048 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20049         JOBENV=PBS_JOBID
20050 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20051         JOBENV=LOADL_STEP_ID
20052 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20053         JOBENV=JOB_ID
20054 else
20055         $LCTL list_param jobid_name > /dev/null 2>&1
20056         if [ $? -eq 0 ]; then
20057                 JOBENV=nodelocal
20058         else
20059                 JOBENV=FAKE_JOBID
20060         fi
20061 fi
20062 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20063
20064 verify_jobstats() {
20065         local cmd=($1)
20066         shift
20067         local facets="$@"
20068
20069 # we don't really need to clear the stats for this test to work, since each
20070 # command has a unique jobid, but it makes debugging easier if needed.
20071 #       for facet in $facets; do
20072 #               local dev=$(convert_facet2label $facet)
20073 #               # clear old jobstats
20074 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20075 #       done
20076
20077         # use a new JobID for each test, or we might see an old one
20078         [ "$JOBENV" = "FAKE_JOBID" ] &&
20079                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20080
20081         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20082
20083         [ "$JOBENV" = "nodelocal" ] && {
20084                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20085                 $LCTL set_param jobid_name=$FAKE_JOBID
20086                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20087         }
20088
20089         log "Test: ${cmd[*]}"
20090         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20091
20092         if [ $JOBENV = "FAKE_JOBID" ]; then
20093                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20094         else
20095                 ${cmd[*]}
20096         fi
20097
20098         # all files are created on OST0000
20099         for facet in $facets; do
20100                 local stats="*.$(convert_facet2label $facet).job_stats"
20101
20102                 # strip out libtool wrappers for in-tree executables
20103                 if (( $(do_facet $facet lctl get_param $stats |
20104                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20105                         do_facet $facet lctl get_param $stats
20106                         error "No jobstats for $JOBVAL found on $facet::$stats"
20107                 fi
20108         done
20109 }
20110
20111 jobstats_set() {
20112         local new_jobenv=$1
20113
20114         set_persistent_param_and_check client "jobid_var" \
20115                 "$FSNAME.sys.jobid_var" $new_jobenv
20116 }
20117
20118 test_205a() { # Job stats
20119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20120         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20121                 skip "Need MDS version with at least 2.7.1"
20122         remote_mgs_nodsh && skip "remote MGS with nodsh"
20123         remote_mds_nodsh && skip "remote MDS with nodsh"
20124         remote_ost_nodsh && skip "remote OST with nodsh"
20125         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20126                 skip "Server doesn't support jobstats"
20127         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20128
20129         local old_jobenv=$($LCTL get_param -n jobid_var)
20130         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20131         stack_trap "jobstats_set $old_jobenv" EXIT
20132
20133         changelog_register
20134
20135         local old_jobid_name=$($LCTL get_param jobid_name)
20136         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20137
20138         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20139                                 mdt.*.job_cleanup_interval | head -n 1)
20140         local new_interval=5
20141         do_facet $SINGLEMDS \
20142                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20143         stack_trap "do_facet $SINGLEMDS \
20144                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20145         local start=$SECONDS
20146
20147         local cmd
20148         # mkdir
20149         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20150         verify_jobstats "$cmd" "$SINGLEMDS"
20151         # rmdir
20152         cmd="rmdir $DIR/$tdir"
20153         verify_jobstats "$cmd" "$SINGLEMDS"
20154         # mkdir on secondary MDT
20155         if [ $MDSCOUNT -gt 1 ]; then
20156                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20157                 verify_jobstats "$cmd" "mds2"
20158         fi
20159         # mknod
20160         cmd="mknod $DIR/$tfile c 1 3"
20161         verify_jobstats "$cmd" "$SINGLEMDS"
20162         # unlink
20163         cmd="rm -f $DIR/$tfile"
20164         verify_jobstats "$cmd" "$SINGLEMDS"
20165         # create all files on OST0000 so verify_jobstats can find OST stats
20166         # open & close
20167         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20168         verify_jobstats "$cmd" "$SINGLEMDS"
20169         # setattr
20170         cmd="touch $DIR/$tfile"
20171         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20172         # write
20173         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20174         verify_jobstats "$cmd" "ost1"
20175         # read
20176         cancel_lru_locks osc
20177         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20178         verify_jobstats "$cmd" "ost1"
20179         # truncate
20180         cmd="$TRUNCATE $DIR/$tfile 0"
20181         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20182         # rename
20183         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20184         verify_jobstats "$cmd" "$SINGLEMDS"
20185         # jobstats expiry - sleep until old stats should be expired
20186         local left=$((new_interval + 5 - (SECONDS - start)))
20187         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20188                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20189                         "0" $left
20190         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20191         verify_jobstats "$cmd" "$SINGLEMDS"
20192         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20193             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20194
20195         # Ensure that jobid are present in changelog (if supported by MDS)
20196         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20197                 changelog_dump | tail -10
20198                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20199                 [ $jobids -eq 9 ] ||
20200                         error "Wrong changelog jobid count $jobids != 9"
20201
20202                 # LU-5862
20203                 JOBENV="disable"
20204                 jobstats_set $JOBENV
20205                 touch $DIR/$tfile
20206                 changelog_dump | grep $tfile
20207                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20208                 [ $jobids -eq 0 ] ||
20209                         error "Unexpected jobids when jobid_var=$JOBENV"
20210         fi
20211
20212         # test '%j' access to environment variable - if supported
20213         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20214                 JOBENV="JOBCOMPLEX"
20215                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20216
20217                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20218         fi
20219
20220         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20221                 JOBENV="JOBCOMPLEX"
20222                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20223
20224                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20225         fi
20226
20227         # test '%j' access to per-session jobid - if supported
20228         if lctl list_param jobid_this_session > /dev/null 2>&1
20229         then
20230                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20231                 lctl set_param jobid_this_session=$USER
20232
20233                 JOBENV="JOBCOMPLEX"
20234                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20235
20236                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20237         fi
20238 }
20239 run_test 205a "Verify job stats"
20240
20241 # LU-13117, LU-13597, LU-16599
20242 test_205b() {
20243         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20244                 skip "Need MDS version at least 2.13.54.91"
20245
20246         local job_stats="mdt.*.job_stats"
20247         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20248
20249         do_facet mds1 $LCTL set_param $job_stats=clear
20250
20251         # Setting jobid_var to USER might not be supported
20252         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20253         $LCTL set_param jobid_var=USER || true
20254         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20255         $LCTL set_param jobid_name="%j.%e.%u"
20256
20257         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20258         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20259                 { do_facet mds1 $LCTL get_param $job_stats;
20260                   error "Unexpected jobid found"; }
20261         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20262                 { do_facet mds1 $LCTL get_param $job_stats;
20263                   error "wrong job_stats format found"; }
20264
20265         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20266                 echo "MDS does not yet escape jobid" && return 0
20267
20268         mkdir_on_mdt0 $DIR/$tdir
20269         $LCTL set_param jobid_var=TEST205b
20270         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20271         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20272                       awk '/has\\x20sp/ {print $3}')
20273         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20274                   error "jobid not escaped"; }
20275
20276         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20277                 # need to run such a command on mds1:
20278                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20279                 #
20280                 # there might be multiple MDTs on single mds server, so need to
20281                 # specifiy MDT0000. Or the command will fail due to other MDTs
20282                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20283                         error "cannot clear escaped jobid in job_stats";
20284         else
20285                 echo "MDS does not support clearing escaped jobid"
20286         fi
20287 }
20288 run_test 205b "Verify job stats jobid and output format"
20289
20290 # LU-13733
20291 test_205c() {
20292         $LCTL set_param llite.*.stats=0
20293         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20294         $LCTL get_param llite.*.stats
20295         $LCTL get_param llite.*.stats | grep \
20296                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20297                         error "wrong client stats format found"
20298 }
20299 run_test 205c "Verify client stats format"
20300
20301 test_205d() {
20302         local file=$DIR/$tdir/$tfile
20303
20304         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20305                 skip "need lustre >= 2.15.53 for lljobstat"
20306         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20307                 skip "need lustre >= 2.15.53 for lljobstat"
20308         verify_yaml_available || skip_env "YAML verification not installed"
20309
20310         test_mkdir -i 0 $DIR/$tdir
20311         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20312         stack_trap "rm -rf $DIR/$tdir"
20313
20314         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20315                 error "failed to write data to $file"
20316         mv $file $file.2
20317
20318         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20319         echo -n 'verify rename_stats...'
20320         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20321                 verify_yaml || error "rename_stats is not valid YAML"
20322         echo " OK"
20323
20324         echo -n 'verify mdt job_stats...'
20325         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20326                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20327         echo " OK"
20328
20329         echo -n 'verify ost job_stats...'
20330         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20331                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20332         echo " OK"
20333 }
20334 run_test 205d "verify the format of some stats files"
20335
20336 test_205e() {
20337         local ops_comma
20338         local file=$DIR/$tdir/$tfile
20339         local -a cli_params
20340
20341         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20342                 skip "need lustre >= 2.15.53 for lljobstat"
20343         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20344                 skip "need lustre >= 2.15.53 for lljobstat"
20345         verify_yaml_available || skip_env "YAML verification not installed"
20346
20347         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20348         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20349         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20350
20351         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20352         stack_trap "rm -rf $DIR/$tdir"
20353
20354         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20355                 error "failed to create $file on ost1"
20356         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20357                 error "failed to write data to $file"
20358
20359         do_facet mds1 "$LCTL get_param *.*.job_stats"
20360         do_facet ost1 "$LCTL get_param *.*.job_stats"
20361
20362         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20363         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20364                 error "The output of lljobstat is not an valid YAML"
20365
20366         # verify that job dd.0 does exist and has some ops on ost1
20367         # typically this line is like:
20368         # - 205e.dd.0:            {ops: 20, ...}
20369         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20370                     awk '$2=="205e.dd.0:" {print $4}')
20371
20372         (( ${ops_comma%,} >= 10 )) ||
20373                 error "cannot find job 205e.dd.0 with ops >= 10"
20374 }
20375 run_test 205e "verify the output of lljobstat"
20376
20377 test_205f() {
20378         verify_yaml_available || skip_env "YAML verification not installed"
20379
20380         # check both qos_ost_weights and qos_mdt_weights
20381         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20382         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20383                 error "qos_ost_weights is not valid YAML"
20384 }
20385 run_test 205f "verify qos_ost_weights YAML format "
20386
20387 __test_205_jobstats_dump() {
20388         local -a pids
20389         local nbr_instance=$1
20390
20391         while true; do
20392                 if (( ${#pids[@]} >= nbr_instance )); then
20393                         wait ${pids[@]}
20394                         pids=()
20395                 fi
20396
20397                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20398                 pids+=( $! )
20399         done
20400 }
20401
20402 __test_205_cleanup() {
20403         kill $@
20404         # Clear all job entries
20405         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20406 }
20407
20408 test_205g() {
20409         local -a mds1_params
20410         local -a cli_params
20411         local pids
20412         local interval=5
20413
20414         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20415         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20416         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20417
20418         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20419         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20420         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20421
20422         # start jobs loop
20423         export TEST205G_ID=205g
20424         stack_trap "unset TEST205G_ID" EXIT
20425         while true; do
20426                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20427         done & pids="$! "
20428
20429         __test_205_jobstats_dump 4 & pids+="$! "
20430         stack_trap "__test_205_cleanup $pids" EXIT INT
20431
20432         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20433 }
20434 run_test 205g "stress test for job_stats procfile"
20435
20436 test_205h() {
20437         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20438                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20439         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20440
20441         local dir=$DIR/$tdir
20442         local f=$dir/$tfile
20443         local f2=$dir/$tfile-2
20444         local f3=$dir/$tfile-3
20445         local subdir=$DIR/dir
20446         local val
20447
20448         local mdts=$(comma_list $(mdts_nodes))
20449         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20450         local client_saved=$($LCTL get_param -n jobid_var)
20451
20452         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20453         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20454
20455         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20456                 error "failed to set job_xattr parameter to user.job"
20457         $LCTL set_param jobid_var=procname.uid ||
20458                 error "failed to set jobid_var parameter"
20459
20460         test_mkdir $dir
20461
20462         touch $f
20463         val=$(getfattr -n user.job $f | grep user.job)
20464         [[ $val = user.job=\"touch.0\" ]] ||
20465                 error "expected user.job=\"touch.0\", got '$val'"
20466
20467         mkdir $subdir
20468         val=$(getfattr -n user.job $subdir | grep user.job)
20469         [[ $val = user.job=\"mkdir.0\" ]] ||
20470                 error "expected user.job=\"mkdir.0\", got '$val'"
20471
20472         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20473                 error "failed to set job_xattr parameter to NONE"
20474
20475         touch $f2
20476         val=$(getfattr -d $f2)
20477         [[ -z $val ]] ||
20478                 error "expected no user xattr, got '$val'"
20479
20480         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20481                 error "failed to set job_xattr parameter to trusted.job"
20482
20483         touch $f3
20484         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20485         [[ $val = trusted.job=\"touch.0\" ]] ||
20486                 error "expected trusted.job=\"touch.0\", got '$val'"
20487 }
20488 run_test 205h "check jobid xattr is stored correctly"
20489
20490 test_205i() {
20491         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20492                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20493
20494         local mdts=$(comma_list $(mdts_nodes))
20495         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20496
20497         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20498
20499         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20500                 error "failed to set mdt.*.job_xattr to user.1234567"
20501
20502         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20503                 error "failed to reject too long job_xattr name"
20504
20505         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20506                 error "failed to reject job_xattr name in bad format"
20507
20508         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20509                 error "failed to reject job_xattr name with invalid character"
20510
20511         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20512                         xargs $LCTL set_param" &&
20513                 error "failed to reject job_xattr name with non-ascii character"
20514
20515         return 0
20516 }
20517 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20518
20519 # LU-1480, LU-1773 and LU-1657
20520 test_206() {
20521         mkdir -p $DIR/$tdir
20522         $LFS setstripe -c -1 $DIR/$tdir
20523 #define OBD_FAIL_LOV_INIT 0x1403
20524         $LCTL set_param fail_loc=0xa0001403
20525         $LCTL set_param fail_val=1
20526         touch $DIR/$tdir/$tfile || true
20527 }
20528 run_test 206 "fail lov_init_raid0() doesn't lbug"
20529
20530 test_207a() {
20531         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20532         local fsz=`stat -c %s $DIR/$tfile`
20533         cancel_lru_locks mdc
20534
20535         # do not return layout in getattr intent
20536 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20537         $LCTL set_param fail_loc=0x170
20538         local sz=`stat -c %s $DIR/$tfile`
20539
20540         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20541
20542         rm -rf $DIR/$tfile
20543 }
20544 run_test 207a "can refresh layout at glimpse"
20545
20546 test_207b() {
20547         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20548         local cksum=`md5sum $DIR/$tfile`
20549         local fsz=`stat -c %s $DIR/$tfile`
20550         cancel_lru_locks mdc
20551         cancel_lru_locks osc
20552
20553         # do not return layout in getattr intent
20554 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20555         $LCTL set_param fail_loc=0x171
20556
20557         # it will refresh layout after the file is opened but before read issues
20558         echo checksum is "$cksum"
20559         echo "$cksum" |md5sum -c --quiet || error "file differs"
20560
20561         rm -rf $DIR/$tfile
20562 }
20563 run_test 207b "can refresh layout at open"
20564
20565 test_208() {
20566         # FIXME: in this test suite, only RD lease is used. This is okay
20567         # for now as only exclusive open is supported. After generic lease
20568         # is done, this test suite should be revised. - Jinshan
20569
20570         remote_mds_nodsh && skip "remote MDS with nodsh"
20571         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20572                 skip "Need MDS version at least 2.4.52"
20573
20574         echo "==== test 1: verify get lease work"
20575         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20576
20577         echo "==== test 2: verify lease can be broken by upcoming open"
20578         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20579         local PID=$!
20580         sleep 2
20581
20582         $MULTIOP $DIR/$tfile oO_RDWR:c
20583         kill -USR1 $PID && wait $PID || error "break lease error"
20584
20585         echo "==== test 3: verify lease can't be granted if an open already exists"
20586         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20587         local PID=$!
20588         sleep 2
20589
20590         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20591         kill -USR1 $PID && wait $PID || error "open file error"
20592
20593         echo "==== test 4: lease can sustain over recovery"
20594         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20595         PID=$!
20596         sleep 2
20597
20598         fail mds1
20599
20600         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20601
20602         echo "==== test 5: lease broken can't be regained by replay"
20603         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20604         PID=$!
20605         sleep 2
20606
20607         # open file to break lease and then recovery
20608         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20609         fail mds1
20610
20611         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20612
20613         rm -f $DIR/$tfile
20614 }
20615 run_test 208 "Exclusive open"
20616
20617 test_209() {
20618         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20619                 skip_env "must have disp_stripe"
20620
20621         touch $DIR/$tfile
20622         sync; sleep 5; sync;
20623
20624         echo 3 > /proc/sys/vm/drop_caches
20625         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20626                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20627         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20628
20629         # open/close 500 times
20630         for i in $(seq 500); do
20631                 cat $DIR/$tfile
20632         done
20633
20634         echo 3 > /proc/sys/vm/drop_caches
20635         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20636                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20637         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20638
20639         echo "before: $req_before, after: $req_after"
20640         [ $((req_after - req_before)) -ge 300 ] &&
20641                 error "open/close requests are not freed"
20642         return 0
20643 }
20644 run_test 209 "read-only open/close requests should be freed promptly"
20645
20646 test_210() {
20647         local pid
20648
20649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20650         pid=$!
20651         sleep 1
20652
20653         $LFS getstripe $DIR/$tfile
20654         kill -USR1 $pid
20655         wait $pid || error "multiop failed"
20656
20657         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20658         pid=$!
20659         sleep 1
20660
20661         $LFS getstripe $DIR/$tfile
20662         kill -USR1 $pid
20663         wait $pid || error "multiop failed"
20664 }
20665 run_test 210 "lfs getstripe does not break leases"
20666
20667 function test_211() {
20668         local PID
20669         local id
20670         local rc
20671
20672         stack_trap "rm -f $DIR/$tfile" EXIT
20673         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20674                 error "can't create file"
20675         $LFS mirror extend -N $DIR/$tfile ||
20676                 error "can't create a replica"
20677         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20678         $LFS getstripe $DIR/$tfile
20679         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20680         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20681
20682         $MULTIOP $DIR/$tfile OeW_E+eUc &
20683         PID=$!
20684         sleep 0.3
20685
20686         id=$($LFS getstripe $DIR/$tfile |
20687                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20688         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20689                 error "removed last in-sync replica?"
20690
20691         kill -USR1 $PID
20692         wait $PID
20693         (( $? == 0 )) || error "failed split broke the lease"
20694 }
20695 run_test 211 "failed mirror split doesn't break write lease"
20696
20697 test_212() {
20698         size=`date +%s`
20699         size=$((size % 8192 + 1))
20700         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20701         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20702         rm -f $DIR/f212 $DIR/f212.xyz
20703 }
20704 run_test 212 "Sendfile test ============================================"
20705
20706 test_213() {
20707         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20708         cancel_lru_locks osc
20709         lctl set_param fail_loc=0x8000040f
20710         # generate a read lock
20711         cat $DIR/$tfile > /dev/null
20712         # write to the file, it will try to cancel the above read lock.
20713         cat /etc/hosts >> $DIR/$tfile
20714 }
20715 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20716
20717 test_214() { # for bug 20133
20718         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20719         for (( i=0; i < 340; i++ )) ; do
20720                 touch $DIR/$tdir/d214c/a$i
20721         done
20722
20723         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20724         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20725         ls $DIR/d214c || error "ls $DIR/d214c failed"
20726         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20727         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20728 }
20729 run_test 214 "hash-indexed directory test - bug 20133"
20730
20731 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20732 create_lnet_proc_files() {
20733         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20734 }
20735
20736 # counterpart of create_lnet_proc_files
20737 remove_lnet_proc_files() {
20738         rm -f $TMP/lnet_$1.sys
20739 }
20740
20741 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20742 # 3rd arg as regexp for body
20743 check_lnet_proc_stats() {
20744         local l=$(cat "$TMP/lnet_$1" |wc -l)
20745         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20746
20747         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20748 }
20749
20750 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20751 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20752 # optional and can be regexp for 2nd line (lnet.routes case)
20753 check_lnet_proc_entry() {
20754         local blp=2          # blp stands for 'position of 1st line of body'
20755         [ -z "$5" ] || blp=3 # lnet.routes case
20756
20757         local l=$(cat "$TMP/lnet_$1" |wc -l)
20758         # subtracting one from $blp because the body can be empty
20759         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20760
20761         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20762                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20763
20764         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20765                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20766
20767         # bail out if any unexpected line happened
20768         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20769         [ "$?" != 0 ] || error "$2 misformatted"
20770 }
20771
20772 test_215() { # for bugs 18102, 21079, 21517
20773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20774
20775         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20776         local P='[1-9][0-9]*'           # positive numeric
20777         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20778         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20779         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20780         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20781
20782         local L1 # regexp for 1st line
20783         local L2 # regexp for 2nd line (optional)
20784         local BR # regexp for the rest (body)
20785
20786         # lnet.stats should look as 11 space-separated non-negative numerics
20787         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20788         create_lnet_proc_files "stats"
20789         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20790         remove_lnet_proc_files "stats"
20791
20792         # lnet.routes should look like this:
20793         # Routing disabled/enabled
20794         # net hops priority state router
20795         # where net is a string like tcp0, hops > 0, priority >= 0,
20796         # state is up/down,
20797         # router is a string like 192.168.1.1@tcp2
20798         L1="^Routing (disabled|enabled)$"
20799         L2="^net +hops +priority +state +router$"
20800         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20801         create_lnet_proc_files "routes"
20802         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20803         remove_lnet_proc_files "routes"
20804
20805         # lnet.routers should look like this:
20806         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20807         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20808         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20809         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20810         L1="^ref +rtr_ref +alive +router$"
20811         BR="^$P +$P +(up|down) +$NID$"
20812         create_lnet_proc_files "routers"
20813         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20814         remove_lnet_proc_files "routers"
20815
20816         # lnet.peers should look like this:
20817         # nid refs state last max rtr min tx min queue
20818         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20819         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20820         # numeric (0 or >0 or <0), queue >= 0.
20821         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20822         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20823         create_lnet_proc_files "peers"
20824         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20825         remove_lnet_proc_files "peers"
20826
20827         # lnet.buffers  should look like this:
20828         # pages count credits min
20829         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20830         L1="^pages +count +credits +min$"
20831         BR="^ +$N +$N +$I +$I$"
20832         create_lnet_proc_files "buffers"
20833         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20834         remove_lnet_proc_files "buffers"
20835
20836         # lnet.nis should look like this:
20837         # nid status alive refs peer rtr max tx min
20838         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20839         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20840         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20841         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20842         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20843         create_lnet_proc_files "nis"
20844         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20845         remove_lnet_proc_files "nis"
20846
20847         # can we successfully write to lnet.stats?
20848         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20849 }
20850 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20851
20852 test_216() { # bug 20317
20853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20854         remote_ost_nodsh && skip "remote OST with nodsh"
20855
20856         local node
20857         local facets=$(get_facets OST)
20858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20859
20860         save_lustre_params client "osc.*.contention_seconds" > $p
20861         save_lustre_params $facets \
20862                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20863         save_lustre_params $facets \
20864                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20865         save_lustre_params $facets \
20866                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20867         clear_stats osc.*.osc_stats
20868
20869         # agressive lockless i/o settings
20870         do_nodes $(comma_list $(osts_nodes)) \
20871                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20872                         ldlm.namespaces.filter-*.contended_locks=0 \
20873                         ldlm.namespaces.filter-*.contention_seconds=60"
20874         lctl set_param -n osc.*.contention_seconds=60
20875
20876         $DIRECTIO write $DIR/$tfile 0 10 4096
20877         $CHECKSTAT -s 40960 $DIR/$tfile
20878
20879         # disable lockless i/o
20880         do_nodes $(comma_list $(osts_nodes)) \
20881                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20882                         ldlm.namespaces.filter-*.contended_locks=32 \
20883                         ldlm.namespaces.filter-*.contention_seconds=0"
20884         lctl set_param -n osc.*.contention_seconds=0
20885         clear_stats osc.*.osc_stats
20886
20887         dd if=/dev/zero of=$DIR/$tfile count=0
20888         $CHECKSTAT -s 0 $DIR/$tfile
20889
20890         restore_lustre_params <$p
20891         rm -f $p
20892         rm $DIR/$tfile
20893 }
20894 run_test 216 "check lockless direct write updates file size and kms correctly"
20895
20896 test_217() { # bug 22430
20897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20898
20899         local node
20900
20901         for node in $(nodes_list); do
20902                 local nid=$(host_nids_address $node $NETTYPE)
20903                 local node_ip=$(do_node $node getent ahostsv4 $node |
20904                                 awk '{ print $1; exit; }')
20905
20906                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20907                 # if hostname matches any NID, use hostname for better testing
20908                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20909                         echo "lctl ping node $node@$NETTYPE"
20910                         lctl ping $node@$NETTYPE
20911                 else # otherwise, at least test 'lctl ping' is working
20912                         echo "lctl ping nid $(h2nettype $nid)"
20913                         lctl ping $(h2nettype $nid)
20914                         echo "skipping $node (no hyphen detected)"
20915                 fi
20916         done
20917 }
20918 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20919
20920 test_218() {
20921         # do directio so as not to populate the page cache
20922         log "creating a 10 Mb file"
20923         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20924                 error "multiop failed while creating a file"
20925         log "starting reads"
20926         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20927         log "truncating the file"
20928         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20929                 error "multiop failed while truncating the file"
20930         log "killing dd"
20931         kill %+ || true # reads might have finished
20932         echo "wait until dd is finished"
20933         wait
20934         log "removing the temporary file"
20935         rm -rf $DIR/$tfile || error "tmp file removal failed"
20936 }
20937 run_test 218 "parallel read and truncate should not deadlock"
20938
20939 test_219() {
20940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20941
20942         # write one partial page
20943         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20944         # set no grant so vvp_io_commit_write will do sync write
20945         $LCTL set_param fail_loc=0x411
20946         # write a full page at the end of file
20947         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20948
20949         $LCTL set_param fail_loc=0
20950         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20951         $LCTL set_param fail_loc=0x411
20952         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20953
20954         # LU-4201
20955         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20956         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20957 }
20958 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20959
20960 test_220() { #LU-325
20961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20962         remote_ost_nodsh && skip "remote OST with nodsh"
20963         remote_mds_nodsh && skip "remote MDS with nodsh"
20964         remote_mgs_nodsh && skip "remote MGS with nodsh"
20965
20966         local OSTIDX=0
20967
20968         # create on MDT0000 so the last_id and next_id are correct
20969         mkdir_on_mdt0 $DIR/$tdir
20970         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20971         OST=${OST%_UUID}
20972
20973         # on the mdt's osc
20974         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20975         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20976                         osp.$mdtosc_proc1.prealloc_last_id)
20977         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20978                         osp.$mdtosc_proc1.prealloc_next_id)
20979
20980         $LFS df -i
20981
20982         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20983         #define OBD_FAIL_OST_ENOINO              0x229
20984         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20985         create_pool $FSNAME.$TESTNAME || return 1
20986         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20987
20988         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20989
20990         MDSOBJS=$((last_id - next_id))
20991         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20992
20993         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20994         echo "OST still has $count kbytes free"
20995
20996         echo "create $MDSOBJS files @next_id..."
20997         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20998
20999         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21000                         osp.$mdtosc_proc1.prealloc_last_id)
21001         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21002                         osp.$mdtosc_proc1.prealloc_next_id)
21003
21004         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21005         $LFS df -i
21006
21007         echo "cleanup..."
21008
21009         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21010         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21011
21012         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21013                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21014         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21015                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21016         echo "unlink $MDSOBJS files @$next_id..."
21017         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21018 }
21019 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21020
21021 test_221() {
21022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21023
21024         dd if=`which date` of=$MOUNT/date oflag=sync
21025         chmod +x $MOUNT/date
21026
21027         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21028         $LCTL set_param fail_loc=0x80001401
21029
21030         $MOUNT/date > /dev/null
21031         rm -f $MOUNT/date
21032 }
21033 run_test 221 "make sure fault and truncate race to not cause OOM"
21034
21035 test_222a () {
21036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21037
21038         rm -rf $DIR/$tdir
21039         test_mkdir $DIR/$tdir
21040         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21041         createmany -o $DIR/$tdir/$tfile 10
21042         cancel_lru_locks mdc
21043         cancel_lru_locks osc
21044         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21045         $LCTL set_param fail_loc=0x31a
21046         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21047         $LCTL set_param fail_loc=0
21048         rm -r $DIR/$tdir
21049 }
21050 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21051
21052 test_222b () {
21053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21054
21055         rm -rf $DIR/$tdir
21056         test_mkdir $DIR/$tdir
21057         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21058         createmany -o $DIR/$tdir/$tfile 10
21059         cancel_lru_locks mdc
21060         cancel_lru_locks osc
21061         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21062         $LCTL set_param fail_loc=0x31a
21063         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21064         $LCTL set_param fail_loc=0
21065 }
21066 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21067
21068 test_223 () {
21069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21070
21071         rm -rf $DIR/$tdir
21072         test_mkdir $DIR/$tdir
21073         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21074         createmany -o $DIR/$tdir/$tfile 10
21075         cancel_lru_locks mdc
21076         cancel_lru_locks osc
21077         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21078         $LCTL set_param fail_loc=0x31b
21079         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21080         $LCTL set_param fail_loc=0
21081         rm -r $DIR/$tdir
21082 }
21083 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21084
21085 test_224a() { # LU-1039, MRP-303
21086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21087         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21088         $LCTL set_param fail_loc=0x508
21089         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21090         $LCTL set_param fail_loc=0
21091         df $DIR
21092 }
21093 run_test 224a "Don't panic on bulk IO failure"
21094
21095 test_224bd_sub() { # LU-1039, MRP-303
21096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21097         local timeout=$1
21098
21099         shift
21100         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21101
21102         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21103
21104         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21105         cancel_lru_locks osc
21106         set_checksums 0
21107         stack_trap "set_checksums $ORIG_CSUM" EXIT
21108         local at_max_saved=0
21109
21110         # adaptive timeouts may prevent seeing the issue
21111         if at_is_enabled; then
21112                 at_max_saved=$(at_max_get mds)
21113                 at_max_set 0 mds client
21114                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21115         fi
21116
21117         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21118         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21119         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21120
21121         do_facet ost1 $LCTL set_param fail_loc=0
21122         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21123         df $DIR
21124 }
21125
21126 test_224b() {
21127         test_224bd_sub 3 error "dd failed"
21128 }
21129 run_test 224b "Don't panic on bulk IO failure"
21130
21131 test_224c() { # LU-6441
21132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21133         remote_mds_nodsh && skip "remote MDS with nodsh"
21134
21135         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21136         save_writethrough $p
21137         set_cache writethrough on
21138
21139         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21140         local at_max=$($LCTL get_param -n at_max)
21141         local timeout=$($LCTL get_param -n timeout)
21142         local test_at="at_max"
21143         local param_at="$FSNAME.sys.at_max"
21144         local test_timeout="timeout"
21145         local param_timeout="$FSNAME.sys.timeout"
21146
21147         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21148
21149         set_persistent_param_and_check client "$test_at" "$param_at" 0
21150         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21151
21152         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21153         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21154         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21155         stack_trap "rm -f $DIR/$tfile"
21156         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21157         sync
21158         do_facet ost1 "$LCTL set_param fail_loc=0"
21159
21160         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21161         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21162                 $timeout
21163
21164         $LCTL set_param -n $pages_per_rpc
21165         restore_lustre_params < $p
21166         rm -f $p
21167 }
21168 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21169
21170 test_224d() { # LU-11169
21171         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21172 }
21173 run_test 224d "Don't corrupt data on bulk IO timeout"
21174
21175 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21176 test_225a () {
21177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21178         if [ -z ${MDSSURVEY} ]; then
21179                 skip_env "mds-survey not found"
21180         fi
21181         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21182                 skip "Need MDS version at least 2.2.51"
21183
21184         local mds=$(facet_host $SINGLEMDS)
21185         local target=$(do_nodes $mds 'lctl dl' |
21186                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21187
21188         local cmd1="file_count=1000 thrhi=4"
21189         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21190         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21191         local cmd="$cmd1 $cmd2 $cmd3"
21192
21193         rm -f ${TMP}/mds_survey*
21194         echo + $cmd
21195         eval $cmd || error "mds-survey with zero-stripe failed"
21196         cat ${TMP}/mds_survey*
21197         rm -f ${TMP}/mds_survey*
21198 }
21199 run_test 225a "Metadata survey sanity with zero-stripe"
21200
21201 test_225b () {
21202         if [ -z ${MDSSURVEY} ]; then
21203                 skip_env "mds-survey not found"
21204         fi
21205         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21206                 skip "Need MDS version at least 2.2.51"
21207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21208         remote_mds_nodsh && skip "remote MDS with nodsh"
21209         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21210                 skip_env "Need to mount OST to test"
21211         fi
21212
21213         local mds=$(facet_host $SINGLEMDS)
21214         local target=$(do_nodes $mds 'lctl dl' |
21215                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21216
21217         local cmd1="file_count=1000 thrhi=4"
21218         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21219         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21220         local cmd="$cmd1 $cmd2 $cmd3"
21221
21222         rm -f ${TMP}/mds_survey*
21223         echo + $cmd
21224         eval $cmd || error "mds-survey with stripe_count failed"
21225         cat ${TMP}/mds_survey*
21226         rm -f ${TMP}/mds_survey*
21227 }
21228 run_test 225b "Metadata survey sanity with stripe_count = 1"
21229
21230 mcreate_path2fid () {
21231         local mode=$1
21232         local major=$2
21233         local minor=$3
21234         local name=$4
21235         local desc=$5
21236         local path=$DIR/$tdir/$name
21237         local fid
21238         local rc
21239         local fid_path
21240
21241         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21242                 error "cannot create $desc"
21243
21244         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21245         rc=$?
21246         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21247
21248         fid_path=$($LFS fid2path $MOUNT $fid)
21249         rc=$?
21250         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21251
21252         [ "$path" == "$fid_path" ] ||
21253                 error "fid2path returned $fid_path, expected $path"
21254
21255         echo "pass with $path and $fid"
21256 }
21257
21258 test_226a () {
21259         rm -rf $DIR/$tdir
21260         mkdir -p $DIR/$tdir
21261
21262         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21263         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21264         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21265         mcreate_path2fid 0040666 0 0 dir "directory"
21266         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21267         mcreate_path2fid 0100666 0 0 file "regular file"
21268         mcreate_path2fid 0120666 0 0 link "symbolic link"
21269         mcreate_path2fid 0140666 0 0 sock "socket"
21270 }
21271 run_test 226a "call path2fid and fid2path on files of all type"
21272
21273 test_226b () {
21274         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21275
21276         local MDTIDX=1
21277
21278         rm -rf $DIR/$tdir
21279         mkdir -p $DIR/$tdir
21280         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21281                 error "create remote directory failed"
21282         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21283         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21284                                 "character special file (null)"
21285         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21286                                 "character special file (no device)"
21287         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21288         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21289                                 "block special file (loop)"
21290         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21291         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21292         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21293 }
21294 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21295
21296 test_226c () {
21297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21298         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21299                 skip "Need MDS version at least 2.13.55"
21300
21301         local submnt=/mnt/submnt
21302         local srcfile=/etc/passwd
21303         local dstfile=$submnt/passwd
21304         local path
21305         local fid
21306
21307         rm -rf $DIR/$tdir
21308         rm -rf $submnt
21309         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21310                 error "create remote directory failed"
21311         mkdir -p $submnt || error "create $submnt failed"
21312         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21313                 error "mount $submnt failed"
21314         stack_trap "umount $submnt" EXIT
21315
21316         cp $srcfile $dstfile
21317         fid=$($LFS path2fid $dstfile)
21318         path=$($LFS fid2path $submnt "$fid")
21319         [ "$path" = "$dstfile" ] ||
21320                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21321 }
21322 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21323
21324 test_226d () {
21325         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21326                 skip "Need client at least version 2.15.57"
21327
21328         # Define First test dataset
21329         local testdirs_01=$DIR/$tdir
21330         local testdata_01=$testdirs_01/${tdir}_01
21331         local testresult_01=${tdir}_01
21332         # Define Second test dataset
21333         local testdirs_02=$DIR/$tdir/$tdir
21334         local testdata_02=$testdirs_02/${tdir}_02
21335         local testresult_02=${tdir}_02
21336         # Define third test dataset (top level)
21337         local testdata_03=$DIR/${tdir}_03
21338         local testresult_03=${tdir}_03
21339
21340         # Create first test dataset
21341         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21342         touch $testdata_01 || error "cannot create file $testdata_01"
21343
21344         # Create second test dataset
21345         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21346         touch $testdata_02 || error "cannot create file $testdata_02"
21347
21348         # Create third test dataset
21349         touch $testdata_03 || error "cannot create file $testdata_03"
21350
21351         local fid01=$($LFS getstripe -F "$testdata_01") ||
21352                 error "getstripe failed on $testdata_01"
21353         local fid02=$($LFS getstripe -F "$testdata_02") ||
21354                 error "getstripe failed on $testdata_01"
21355         local fid03=$($LFS getstripe -F "$testdata_03") ||
21356                 error "getstripe failed on $testdata_03"
21357
21358         # Verify only -n option
21359         local out1=$($LFS fid2path -n $DIR $fid01) ||
21360                 error "fid2path failed on $fid01"
21361         local out2=$($LFS fid2path -n $DIR $fid02) ||
21362                 error "fid2path failed on $fid02"
21363         local out3=$($LFS fid2path -n $DIR $fid03) ||
21364                 error "fid2path failed on $fid03"
21365
21366         [[ "$out1" == "$testresult_01" ]] ||
21367                 error "fid2path failed: Expected $testresult_01 got $out1"
21368         [[ "$out2" == "$testresult_02" ]] ||
21369                 error "fid2path failed: Expected $testresult_02 got $out2"
21370         [[ "$out3" == "$testresult_03" ]] ||
21371                 error "fid2path failed: Expected $testresult_03 got $out3"
21372
21373         # Verify with option -fn together
21374         out1=$($LFS fid2path -fn $DIR $fid01) ||
21375                 error "fid2path -fn failed on $fid01"
21376         out2=$($LFS fid2path -fn $DIR $fid02) ||
21377                 error "fid2path -fn failed on $fid02"
21378         out3=$($LFS fid2path -fn $DIR $fid03) ||
21379                 error "fid2path -fn failed on $fid03"
21380
21381         local tmpout=$(echo $out1 | cut -d" " -f2)
21382         [[ "$tmpout" == "$testresult_01" ]] ||
21383                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21384
21385         tmpout=$(echo $out2 | cut -d" " -f2)
21386         [[ "$tmpout" == "$testresult_02" ]] ||
21387                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21388
21389         tmpout=$(echo $out3 | cut -d" " -f2)
21390         [[ "$tmpout" == "$testresult_03" ]] ||
21391                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21392 }
21393 run_test 226d "verify fid2path with -n and -fn option"
21394
21395 test_226e () {
21396         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21397                 skip "Need client at least version 2.15.56"
21398
21399         # Define filename with 'newline' and a space
21400         local testfile="Test"$'\n'"file 01"
21401         # Define link name with multiple 'newline' and a space
21402         local linkfile="Link"$'\n'"file "$'\n'"01"
21403         # Remove prior hard link
21404         rm -f $DIR/"$linkfile"
21405
21406         # Create file
21407         touch $DIR/"$testfile"
21408         # Create link
21409         ln $DIR/"$testfile" $DIR/"$linkfile"
21410
21411         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21412                 error "getstripe failed on $DIR/$testfile"
21413
21414         # Call with -0 option
21415         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21416                 echo "FILE:" | grep -c "FILE:")
21417
21418         # With -0 option the output should be exactly 2 lines.
21419         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21420 }
21421 run_test 226e "Verify path2fid -0 option with newline and space"
21422
21423 # LU-1299 Executing or running ldd on a truncated executable does not
21424 # cause an out-of-memory condition.
21425 test_227() {
21426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21427         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21428
21429         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21430         chmod +x $MOUNT/date
21431
21432         $MOUNT/date > /dev/null
21433         ldd $MOUNT/date > /dev/null
21434         rm -f $MOUNT/date
21435 }
21436 run_test 227 "running truncated executable does not cause OOM"
21437
21438 # LU-1512 try to reuse idle OI blocks
21439 test_228a() {
21440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21441         remote_mds_nodsh && skip "remote MDS with nodsh"
21442         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21443
21444         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21445         local myDIR=$DIR/$tdir
21446
21447         mkdir -p $myDIR
21448         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21449         $LCTL set_param fail_loc=0x80001002
21450         createmany -o $myDIR/t- 10000
21451         $LCTL set_param fail_loc=0
21452         # The guard is current the largest FID holder
21453         touch $myDIR/guard
21454         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21455                     tr -d '[')
21456         local IDX=$(($SEQ % 64))
21457
21458         do_facet $SINGLEMDS sync
21459         # Make sure journal flushed.
21460         sleep 6
21461         local blk1=$(do_facet $SINGLEMDS \
21462                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21463                      grep Blockcount | awk '{print $4}')
21464
21465         # Remove old files, some OI blocks will become idle.
21466         unlinkmany $myDIR/t- 10000
21467         # Create new files, idle OI blocks should be reused.
21468         createmany -o $myDIR/t- 2000
21469         do_facet $SINGLEMDS sync
21470         # Make sure journal flushed.
21471         sleep 6
21472         local blk2=$(do_facet $SINGLEMDS \
21473                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21474                      grep Blockcount | awk '{print $4}')
21475
21476         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21477 }
21478 run_test 228a "try to reuse idle OI blocks"
21479
21480 test_228b() {
21481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21482         remote_mds_nodsh && skip "remote MDS with nodsh"
21483         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21484
21485         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21486         local myDIR=$DIR/$tdir
21487
21488         mkdir -p $myDIR
21489         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21490         $LCTL set_param fail_loc=0x80001002
21491         createmany -o $myDIR/t- 10000
21492         $LCTL set_param fail_loc=0
21493         # The guard is current the largest FID holder
21494         touch $myDIR/guard
21495         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21496                     tr -d '[')
21497         local IDX=$(($SEQ % 64))
21498
21499         do_facet $SINGLEMDS sync
21500         # Make sure journal flushed.
21501         sleep 6
21502         local blk1=$(do_facet $SINGLEMDS \
21503                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21504                      grep Blockcount | awk '{print $4}')
21505
21506         # Remove old files, some OI blocks will become idle.
21507         unlinkmany $myDIR/t- 10000
21508
21509         # stop the MDT
21510         stop $SINGLEMDS || error "Fail to stop MDT."
21511         # remount the MDT
21512         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21513                 error "Fail to start MDT."
21514
21515         client_up || error "Fail to df."
21516         # Create new files, idle OI blocks should be reused.
21517         createmany -o $myDIR/t- 2000
21518         do_facet $SINGLEMDS sync
21519         # Make sure journal flushed.
21520         sleep 6
21521         local blk2=$(do_facet $SINGLEMDS \
21522                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21523                      grep Blockcount | awk '{print $4}')
21524
21525         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21526 }
21527 run_test 228b "idle OI blocks can be reused after MDT restart"
21528
21529 #LU-1881
21530 test_228c() {
21531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21532         remote_mds_nodsh && skip "remote MDS with nodsh"
21533         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21534
21535         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21536         local myDIR=$DIR/$tdir
21537
21538         mkdir -p $myDIR
21539         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21540         $LCTL set_param fail_loc=0x80001002
21541         # 20000 files can guarantee there are index nodes in the OI file
21542         createmany -o $myDIR/t- 20000
21543         $LCTL set_param fail_loc=0
21544         # The guard is current the largest FID holder
21545         touch $myDIR/guard
21546         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21547                     tr -d '[')
21548         local IDX=$(($SEQ % 64))
21549
21550         do_facet $SINGLEMDS sync
21551         # Make sure journal flushed.
21552         sleep 6
21553         local blk1=$(do_facet $SINGLEMDS \
21554                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21555                      grep Blockcount | awk '{print $4}')
21556
21557         # Remove old files, some OI blocks will become idle.
21558         unlinkmany $myDIR/t- 20000
21559         rm -f $myDIR/guard
21560         # The OI file should become empty now
21561
21562         # Create new files, idle OI blocks should be reused.
21563         createmany -o $myDIR/t- 2000
21564         do_facet $SINGLEMDS sync
21565         # Make sure journal flushed.
21566         sleep 6
21567         local blk2=$(do_facet $SINGLEMDS \
21568                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21569                      grep Blockcount | awk '{print $4}')
21570
21571         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21572 }
21573 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21574
21575 test_229() { # LU-2482, LU-3448
21576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21577         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21578         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21579                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21580
21581         rm -f $DIR/$tfile
21582
21583         # Create a file with a released layout and stripe count 2.
21584         $MULTIOP $DIR/$tfile H2c ||
21585                 error "failed to create file with released layout"
21586
21587         $LFS getstripe -v $DIR/$tfile
21588
21589         local pattern=$($LFS getstripe -L $DIR/$tfile)
21590         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21591
21592         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21593                 error "getstripe"
21594         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21595         stat $DIR/$tfile || error "failed to stat released file"
21596
21597         chown $RUNAS_ID $DIR/$tfile ||
21598                 error "chown $RUNAS_ID $DIR/$tfile failed"
21599
21600         chgrp $RUNAS_ID $DIR/$tfile ||
21601                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21602
21603         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21604         rm $DIR/$tfile || error "failed to remove released file"
21605 }
21606 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21607
21608 test_230a() {
21609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21611         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21612                 skip "Need MDS version at least 2.11.52"
21613
21614         local MDTIDX=1
21615
21616         test_mkdir $DIR/$tdir
21617         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21618         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21619         [ $mdt_idx -ne 0 ] &&
21620                 error "create local directory on wrong MDT $mdt_idx"
21621
21622         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21623                         error "create remote directory failed"
21624         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21625         [ $mdt_idx -ne $MDTIDX ] &&
21626                 error "create remote directory on wrong MDT $mdt_idx"
21627
21628         createmany -o $DIR/$tdir/test_230/t- 10 ||
21629                 error "create files on remote directory failed"
21630         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21631         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21632         rm -r $DIR/$tdir || error "unlink remote directory failed"
21633 }
21634 run_test 230a "Create remote directory and files under the remote directory"
21635
21636 test_230b() {
21637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21639         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21640                 skip "Need MDS version at least 2.11.52"
21641
21642         local MDTIDX=1
21643         local mdt_index
21644         local i
21645         local file
21646         local pid
21647         local stripe_count
21648         local migrate_dir=$DIR/$tdir/migrate_dir
21649         local other_dir=$DIR/$tdir/other_dir
21650
21651         test_mkdir $DIR/$tdir
21652         test_mkdir -i0 -c1 $migrate_dir
21653         test_mkdir -i0 -c1 $other_dir
21654         for ((i=0; i<10; i++)); do
21655                 mkdir -p $migrate_dir/dir_${i}
21656                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21657                         error "create files under remote dir failed $i"
21658         done
21659
21660         cp /etc/passwd $migrate_dir/$tfile
21661         cp /etc/passwd $other_dir/$tfile
21662         chattr +SAD $migrate_dir
21663         chattr +SAD $migrate_dir/$tfile
21664
21665         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21666         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21667         local old_dir_mode=$(stat -c%f $migrate_dir)
21668         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21669
21670         mkdir -p $migrate_dir/dir_default_stripe2
21671         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21672         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21673
21674         mkdir -p $other_dir
21675         ln $migrate_dir/$tfile $other_dir/luna
21676         ln $migrate_dir/$tfile $migrate_dir/sofia
21677         ln $other_dir/$tfile $migrate_dir/david
21678         ln -s $migrate_dir/$tfile $other_dir/zachary
21679         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21680         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21681
21682         local len
21683         local lnktgt
21684
21685         # inline symlink
21686         for len in 58 59 60; do
21687                 lnktgt=$(str_repeat 'l' $len)
21688                 touch $migrate_dir/$lnktgt
21689                 ln -s $lnktgt $migrate_dir/${len}char_ln
21690         done
21691
21692         # PATH_MAX
21693         for len in 4094 4095; do
21694                 lnktgt=$(str_repeat 'l' $len)
21695                 ln -s $lnktgt $migrate_dir/${len}char_ln
21696         done
21697
21698         # NAME_MAX
21699         for len in 254 255; do
21700                 touch $migrate_dir/$(str_repeat 'l' $len)
21701         done
21702
21703         $LFS migrate -m $MDTIDX $migrate_dir ||
21704                 error "fails on migrating remote dir to MDT1"
21705
21706         echo "migratate to MDT1, then checking.."
21707         for ((i = 0; i < 10; i++)); do
21708                 for file in $(find $migrate_dir/dir_${i}); do
21709                         mdt_index=$($LFS getstripe -m $file)
21710                         # broken symlink getstripe will fail
21711                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21712                                 error "$file is not on MDT${MDTIDX}"
21713                 done
21714         done
21715
21716         # the multiple link file should still in MDT0
21717         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21718         [ $mdt_index == 0 ] ||
21719                 error "$file is not on MDT${MDTIDX}"
21720
21721         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21722         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21723                 error " expect $old_dir_flag get $new_dir_flag"
21724
21725         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21726         [ "$old_file_flag" = "$new_file_flag" ] ||
21727                 error " expect $old_file_flag get $new_file_flag"
21728
21729         local new_dir_mode=$(stat -c%f $migrate_dir)
21730         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21731                 error "expect mode $old_dir_mode get $new_dir_mode"
21732
21733         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21734         [ "$old_file_mode" = "$new_file_mode" ] ||
21735                 error "expect mode $old_file_mode get $new_file_mode"
21736
21737         diff /etc/passwd $migrate_dir/$tfile ||
21738                 error "$tfile different after migration"
21739
21740         diff /etc/passwd $other_dir/luna ||
21741                 error "luna different after migration"
21742
21743         diff /etc/passwd $migrate_dir/sofia ||
21744                 error "sofia different after migration"
21745
21746         diff /etc/passwd $migrate_dir/david ||
21747                 error "david different after migration"
21748
21749         diff /etc/passwd $other_dir/zachary ||
21750                 error "zachary different after migration"
21751
21752         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21753                 error "${tfile}_ln different after migration"
21754
21755         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21756                 error "${tfile}_ln_other different after migration"
21757
21758         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21759         [ $stripe_count = 2 ] ||
21760                 error "dir strpe_count $d != 2 after migration."
21761
21762         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21763         [ $stripe_count = 2 ] ||
21764                 error "file strpe_count $d != 2 after migration."
21765
21766         #migrate back to MDT0
21767         MDTIDX=0
21768
21769         $LFS migrate -m $MDTIDX $migrate_dir ||
21770                 error "fails on migrating remote dir to MDT0"
21771
21772         echo "migrate back to MDT0, checking.."
21773         for file in $(find $migrate_dir); do
21774                 mdt_index=$($LFS getstripe -m $file)
21775                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21776                         error "$file is not on MDT${MDTIDX}"
21777         done
21778
21779         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21780         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21781                 error " expect $old_dir_flag get $new_dir_flag"
21782
21783         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21784         [ "$old_file_flag" = "$new_file_flag" ] ||
21785                 error " expect $old_file_flag get $new_file_flag"
21786
21787         local new_dir_mode=$(stat -c%f $migrate_dir)
21788         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21789                 error "expect mode $old_dir_mode get $new_dir_mode"
21790
21791         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21792         [ "$old_file_mode" = "$new_file_mode" ] ||
21793                 error "expect mode $old_file_mode get $new_file_mode"
21794
21795         diff /etc/passwd ${migrate_dir}/$tfile ||
21796                 error "$tfile different after migration"
21797
21798         diff /etc/passwd ${other_dir}/luna ||
21799                 error "luna different after migration"
21800
21801         diff /etc/passwd ${migrate_dir}/sofia ||
21802                 error "sofia different after migration"
21803
21804         diff /etc/passwd ${other_dir}/zachary ||
21805                 error "zachary different after migration"
21806
21807         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21808                 error "${tfile}_ln different after migration"
21809
21810         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21811                 error "${tfile}_ln_other different after migration"
21812
21813         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21814         [ $stripe_count = 2 ] ||
21815                 error "dir strpe_count $d != 2 after migration."
21816
21817         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21818         [ $stripe_count = 2 ] ||
21819                 error "file strpe_count $d != 2 after migration."
21820
21821         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21822 }
21823 run_test 230b "migrate directory"
21824
21825 test_230c() {
21826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21828         remote_mds_nodsh && skip "remote MDS with nodsh"
21829         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21830                 skip "Need MDS version at least 2.11.52"
21831
21832         local MDTIDX=1
21833         local total=3
21834         local mdt_index
21835         local file
21836         local migrate_dir=$DIR/$tdir/migrate_dir
21837
21838         #If migrating directory fails in the middle, all entries of
21839         #the directory is still accessiable.
21840         test_mkdir $DIR/$tdir
21841         test_mkdir -i0 -c1 $migrate_dir
21842         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21843         stat $migrate_dir
21844         createmany -o $migrate_dir/f $total ||
21845                 error "create files under ${migrate_dir} failed"
21846
21847         # fail after migrating top dir, and this will fail only once, so the
21848         # first sub file migration will fail (currently f3), others succeed.
21849         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21850         do_facet mds1 lctl set_param fail_loc=0x1801
21851         local t=$(ls $migrate_dir | wc -l)
21852         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21853                 error "migrate should fail"
21854         local u=$(ls $migrate_dir | wc -l)
21855         [ "$u" == "$t" ] || error "$u != $t during migration"
21856
21857         # add new dir/file should succeed
21858         mkdir $migrate_dir/dir ||
21859                 error "mkdir failed under migrating directory"
21860         touch $migrate_dir/file ||
21861                 error "create file failed under migrating directory"
21862
21863         # add file with existing name should fail
21864         for file in $migrate_dir/f*; do
21865                 stat $file > /dev/null || error "stat $file failed"
21866                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21867                         error "open(O_CREAT|O_EXCL) $file should fail"
21868                 $MULTIOP $file m && error "create $file should fail"
21869                 touch $DIR/$tdir/remote_dir/$tfile ||
21870                         error "touch $tfile failed"
21871                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21872                         error "link $file should fail"
21873                 mdt_index=$($LFS getstripe -m $file)
21874                 if [ $mdt_index == 0 ]; then
21875                         # file failed to migrate is not allowed to rename to
21876                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21877                                 error "rename to $file should fail"
21878                 else
21879                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21880                                 error "rename to $file failed"
21881                 fi
21882                 echo hello >> $file || error "write $file failed"
21883         done
21884
21885         # resume migration with different options should fail
21886         $LFS migrate -m 0 $migrate_dir &&
21887                 error "migrate -m 0 $migrate_dir should fail"
21888
21889         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21890                 error "migrate -c 2 $migrate_dir should fail"
21891
21892         # resume migration should succeed
21893         $LFS migrate -m $MDTIDX $migrate_dir ||
21894                 error "migrate $migrate_dir failed"
21895
21896         echo "Finish migration, then checking.."
21897         for file in $(find $migrate_dir); do
21898                 mdt_index=$($LFS getstripe -m $file)
21899                 [ $mdt_index == $MDTIDX ] ||
21900                         error "$file is not on MDT${MDTIDX}"
21901         done
21902
21903         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21904 }
21905 run_test 230c "check directory accessiblity if migration failed"
21906
21907 test_230d() {
21908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21909         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21910         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21911                 skip "Need MDS version at least 2.11.52"
21912         # LU-11235
21913         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21914
21915         local migrate_dir=$DIR/$tdir/migrate_dir
21916         local old_index
21917         local new_index
21918         local old_count
21919         local new_count
21920         local new_hash
21921         local mdt_index
21922         local i
21923         local j
21924
21925         old_index=$((RANDOM % MDSCOUNT))
21926         old_count=$((MDSCOUNT - old_index))
21927         new_index=$((RANDOM % MDSCOUNT))
21928         new_count=$((MDSCOUNT - new_index))
21929         new_hash=1 # for all_char
21930
21931         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21932         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21933
21934         test_mkdir $DIR/$tdir
21935         test_mkdir -i $old_index -c $old_count $migrate_dir
21936
21937         for ((i=0; i<100; i++)); do
21938                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21939                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21940                         error "create files under remote dir failed $i"
21941         done
21942
21943         echo -n "Migrate from MDT$old_index "
21944         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21945         echo -n "to MDT$new_index"
21946         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21947         echo
21948
21949         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21950         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21951                 error "migrate remote dir error"
21952
21953         echo "Finish migration, then checking.."
21954         for file in $(find $migrate_dir -maxdepth 1); do
21955                 mdt_index=$($LFS getstripe -m $file)
21956                 if [ $mdt_index -lt $new_index ] ||
21957                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21958                         error "$file is on MDT$mdt_index"
21959                 fi
21960         done
21961
21962         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21963 }
21964 run_test 230d "check migrate big directory"
21965
21966 test_230e() {
21967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21969         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21970                 skip "Need MDS version at least 2.11.52"
21971
21972         local i
21973         local j
21974         local a_fid
21975         local b_fid
21976
21977         mkdir_on_mdt0 $DIR/$tdir
21978         mkdir $DIR/$tdir/migrate_dir
21979         mkdir $DIR/$tdir/other_dir
21980         touch $DIR/$tdir/migrate_dir/a
21981         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21982         ls $DIR/$tdir/other_dir
21983
21984         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21985                 error "migrate dir fails"
21986
21987         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21988         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21989
21990         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21991         [ $mdt_index == 0 ] || error "a is not on MDT0"
21992
21993         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21994                 error "migrate dir fails"
21995
21996         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21997         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21998
21999         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22000         [ $mdt_index == 1 ] || error "a is not on MDT1"
22001
22002         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22003         [ $mdt_index == 1 ] || error "b is not on MDT1"
22004
22005         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22006         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22007
22008         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22009
22010         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22011 }
22012 run_test 230e "migrate mulitple local link files"
22013
22014 test_230f() {
22015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22017         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22018                 skip "Need MDS version at least 2.11.52"
22019
22020         local a_fid
22021         local ln_fid
22022
22023         mkdir -p $DIR/$tdir
22024         mkdir $DIR/$tdir/migrate_dir
22025         $LFS mkdir -i1 $DIR/$tdir/other_dir
22026         touch $DIR/$tdir/migrate_dir/a
22027         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22028         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22029         ls $DIR/$tdir/other_dir
22030
22031         # a should be migrated to MDT1, since no other links on MDT0
22032         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22033                 error "#1 migrate dir fails"
22034         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22035         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22036         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22037         [ $mdt_index == 1 ] || error "a is not on MDT1"
22038
22039         # a should stay on MDT1, because it is a mulitple link file
22040         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22041                 error "#2 migrate dir fails"
22042         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22043         [ $mdt_index == 1 ] || error "a is not on MDT1"
22044
22045         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22046                 error "#3 migrate dir fails"
22047
22048         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22049         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22050         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22051
22052         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22053         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22054
22055         # a should be migrated to MDT0, since no other links on MDT1
22056         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22057                 error "#4 migrate dir fails"
22058         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22059         [ $mdt_index == 0 ] || error "a is not on MDT0"
22060
22061         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22062 }
22063 run_test 230f "migrate mulitple remote link files"
22064
22065 test_230g() {
22066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22069                 skip "Need MDS version at least 2.11.52"
22070
22071         mkdir -p $DIR/$tdir/migrate_dir
22072
22073         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22074                 error "migrating dir to non-exist MDT succeeds"
22075         true
22076 }
22077 run_test 230g "migrate dir to non-exist MDT"
22078
22079 test_230h() {
22080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22082         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22083                 skip "Need MDS version at least 2.11.52"
22084
22085         local mdt_index
22086
22087         mkdir -p $DIR/$tdir/migrate_dir
22088
22089         $LFS migrate -m1 $DIR &&
22090                 error "migrating mountpoint1 should fail"
22091
22092         $LFS migrate -m1 $DIR/$tdir/.. &&
22093                 error "migrating mountpoint2 should fail"
22094
22095         # same as mv
22096         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22097                 error "migrating $tdir/migrate_dir/.. should fail"
22098
22099         true
22100 }
22101 run_test 230h "migrate .. and root"
22102
22103 test_230i() {
22104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22106         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22107                 skip "Need MDS version at least 2.11.52"
22108
22109         mkdir -p $DIR/$tdir/migrate_dir
22110
22111         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22112                 error "migration fails with a tailing slash"
22113
22114         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22115                 error "migration fails with two tailing slashes"
22116 }
22117 run_test 230i "lfs migrate -m tolerates trailing slashes"
22118
22119 test_230j() {
22120         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22121         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22122                 skip "Need MDS version at least 2.11.52"
22123
22124         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22125         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22126                 error "create $tfile failed"
22127         cat /etc/passwd > $DIR/$tdir/$tfile
22128
22129         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22130
22131         cmp /etc/passwd $DIR/$tdir/$tfile ||
22132                 error "DoM file mismatch after migration"
22133 }
22134 run_test 230j "DoM file data not changed after dir migration"
22135
22136 test_230k() {
22137         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22138         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22139                 skip "Need MDS version at least 2.11.56"
22140
22141         local total=20
22142         local files_on_starting_mdt=0
22143
22144         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22145         $LFS getdirstripe $DIR/$tdir
22146         for i in $(seq $total); do
22147                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22148                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22149                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22150         done
22151
22152         echo "$files_on_starting_mdt files on MDT0"
22153
22154         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22155         $LFS getdirstripe $DIR/$tdir
22156
22157         files_on_starting_mdt=0
22158         for i in $(seq $total); do
22159                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22160                         error "file $tfile.$i mismatch after migration"
22161                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22162                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22163         done
22164
22165         echo "$files_on_starting_mdt files on MDT1 after migration"
22166         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22167
22168         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22169         $LFS getdirstripe $DIR/$tdir
22170
22171         files_on_starting_mdt=0
22172         for i in $(seq $total); do
22173                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22174                         error "file $tfile.$i mismatch after 2nd migration"
22175                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22176                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22177         done
22178
22179         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22180         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22181
22182         true
22183 }
22184 run_test 230k "file data not changed after dir migration"
22185
22186 test_230l() {
22187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22188         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22189                 skip "Need MDS version at least 2.11.56"
22190
22191         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22192         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22193                 error "create files under remote dir failed $i"
22194         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22195 }
22196 run_test 230l "readdir between MDTs won't crash"
22197
22198 test_230m() {
22199         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22200         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22201                 skip "Need MDS version at least 2.11.56"
22202
22203         local MDTIDX=1
22204         local mig_dir=$DIR/$tdir/migrate_dir
22205         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22206         local shortstr="b"
22207         local val
22208
22209         echo "Creating files and dirs with xattrs"
22210         test_mkdir $DIR/$tdir
22211         test_mkdir -i0 -c1 $mig_dir
22212         mkdir $mig_dir/dir
22213         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22214                 error "cannot set xattr attr1 on dir"
22215         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22216                 error "cannot set xattr attr2 on dir"
22217         touch $mig_dir/dir/f0
22218         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22219                 error "cannot set xattr attr1 on file"
22220         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22221                 error "cannot set xattr attr2 on file"
22222         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22223         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22224         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22225         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22226         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22227         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22228         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22229         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22230         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22231
22232         echo "Migrating to MDT1"
22233         $LFS migrate -m $MDTIDX $mig_dir ||
22234                 error "fails on migrating dir to MDT1"
22235
22236         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22237         echo "Checking xattrs"
22238         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22239         [ "$val" = $longstr ] ||
22240                 error "expecting xattr1 $longstr on dir, found $val"
22241         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22242         [ "$val" = $shortstr ] ||
22243                 error "expecting xattr2 $shortstr on dir, found $val"
22244         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22245         [ "$val" = $longstr ] ||
22246                 error "expecting xattr1 $longstr on file, found $val"
22247         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22248         [ "$val" = $shortstr ] ||
22249                 error "expecting xattr2 $shortstr on file, found $val"
22250 }
22251 run_test 230m "xattrs not changed after dir migration"
22252
22253 test_230n() {
22254         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22255         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22256                 skip "Need MDS version at least 2.13.53"
22257
22258         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22259         cat /etc/hosts > $DIR/$tdir/$tfile
22260         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22261         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22262
22263         cmp /etc/hosts $DIR/$tdir/$tfile ||
22264                 error "File data mismatch after migration"
22265 }
22266 run_test 230n "Dir migration with mirrored file"
22267
22268 test_230o() {
22269         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22270         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22271                 skip "Need MDS version at least 2.13.52"
22272
22273         local mdts=$(comma_list $(mdts_nodes))
22274         local timeout=100
22275         local restripe_status
22276         local delta
22277         local i
22278
22279         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22280
22281         # in case "crush" hash type is not set
22282         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22283
22284         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22285                            mdt.*MDT0000.enable_dir_restripe)
22286         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22287         stack_trap "do_nodes $mdts $LCTL set_param \
22288                     mdt.*.enable_dir_restripe=$restripe_status"
22289
22290         mkdir $DIR/$tdir
22291         createmany -m $DIR/$tdir/f 100 ||
22292                 error "create files under remote dir failed $i"
22293         createmany -d $DIR/$tdir/d 100 ||
22294                 error "create dirs under remote dir failed $i"
22295
22296         for i in $(seq 2 $MDSCOUNT); do
22297                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22298                 $LFS setdirstripe -c $i $DIR/$tdir ||
22299                         error "split -c $i $tdir failed"
22300                 wait_update $HOSTNAME \
22301                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22302                         error "dir split not finished"
22303                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22304                         awk '/migrate/ {sum += $2} END { print sum }')
22305                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22306                 # delta is around total_files/stripe_count
22307                 (( $delta < 200 / (i - 1) + 4 )) ||
22308                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22309         done
22310 }
22311 run_test 230o "dir split"
22312
22313 test_230p() {
22314         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22315         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22316                 skip "Need MDS version at least 2.13.52"
22317
22318         local mdts=$(comma_list $(mdts_nodes))
22319         local timeout=100
22320         local restripe_status
22321         local delta
22322         local c
22323
22324         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22325
22326         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22327
22328         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22329                            mdt.*MDT0000.enable_dir_restripe)
22330         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22331         stack_trap "do_nodes $mdts $LCTL set_param \
22332                     mdt.*.enable_dir_restripe=$restripe_status"
22333
22334         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22335         createmany -m $DIR/$tdir/f 100 ||
22336                 error "create files under remote dir failed"
22337         createmany -d $DIR/$tdir/d 100 ||
22338                 error "create dirs under remote dir failed"
22339
22340         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22341                 local mdt_hash="crush"
22342
22343                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22344                 $LFS setdirstripe -c $c $DIR/$tdir ||
22345                         error "split -c $c $tdir failed"
22346                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22347                         mdt_hash="$mdt_hash,fixed"
22348                 elif [ $c -eq 1 ]; then
22349                         mdt_hash="none"
22350                 fi
22351                 wait_update $HOSTNAME \
22352                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22353                         error "dir merge not finished"
22354                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22355                         awk '/migrate/ {sum += $2} END { print sum }')
22356                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22357                 # delta is around total_files/stripe_count
22358                 (( delta < 200 / c + 4 )) ||
22359                         error "$delta files migrated >= $((200 / c + 4))"
22360         done
22361 }
22362 run_test 230p "dir merge"
22363
22364 test_230q() {
22365         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22366         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22367                 skip "Need MDS version at least 2.13.52"
22368
22369         local mdts=$(comma_list $(mdts_nodes))
22370         local saved_threshold=$(do_facet mds1 \
22371                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22372         local saved_delta=$(do_facet mds1 \
22373                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22374         local threshold=100
22375         local delta=2
22376         local total=0
22377         local stripe_count=0
22378         local stripe_index
22379         local nr_files
22380         local create
22381
22382         # test with fewer files on ZFS
22383         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22384
22385         stack_trap "do_nodes $mdts $LCTL set_param \
22386                     mdt.*.dir_split_count=$saved_threshold"
22387         stack_trap "do_nodes $mdts $LCTL set_param \
22388                     mdt.*.dir_split_delta=$saved_delta"
22389         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22390         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22391         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22392         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22393         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22394         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22395
22396         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22397         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22398
22399         create=$((threshold * 3 / 2))
22400         while [ $stripe_count -lt $MDSCOUNT ]; do
22401                 createmany -m $DIR/$tdir/f $total $create ||
22402                         error "create sub files failed"
22403                 stat $DIR/$tdir > /dev/null
22404                 total=$((total + create))
22405                 stripe_count=$((stripe_count + delta))
22406                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22407
22408                 wait_update $HOSTNAME \
22409                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22410                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22411
22412                 wait_update $HOSTNAME \
22413                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22414                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22415
22416                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22417                 echo "$nr_files/$total files on MDT$stripe_index after split"
22418                 # allow 10% margin of imbalance with crush hash
22419                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22420                         error "$nr_files files on MDT$stripe_index after split"
22421
22422                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22423                 [ $nr_files -eq $total ] ||
22424                         error "total sub files $nr_files != $total"
22425         done
22426
22427         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22428
22429         echo "fixed layout directory won't auto split"
22430         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22431         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22432                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22433         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22434                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22435 }
22436 run_test 230q "dir auto split"
22437
22438 test_230r() {
22439         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22440         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22441         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22442                 skip "Need MDS version at least 2.13.54"
22443
22444         # maximum amount of local locks:
22445         # parent striped dir - 2 locks
22446         # new stripe in parent to migrate to - 1 lock
22447         # source and target - 2 locks
22448         # Total 5 locks for regular file
22449         mkdir -p $DIR/$tdir
22450         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22451         touch $DIR/$tdir/dir1/eee
22452
22453         # create 4 hardlink for 4 more locks
22454         # Total: 9 locks > RS_MAX_LOCKS (8)
22455         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22456         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22457         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22458         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22459         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22460         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22461         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22462         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22463
22464         cancel_lru_locks mdc
22465
22466         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22467                 error "migrate dir fails"
22468
22469         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22470 }
22471 run_test 230r "migrate with too many local locks"
22472
22473 test_230s() {
22474         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22475                 skip "Need MDS version at least 2.14.52"
22476
22477         local mdts=$(comma_list $(mdts_nodes))
22478         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22479                                 mdt.*MDT0000.enable_dir_restripe)
22480
22481         stack_trap "do_nodes $mdts $LCTL set_param \
22482                     mdt.*.enable_dir_restripe=$restripe_status"
22483
22484         local st
22485         for st in 0 1; do
22486                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22487                 test_mkdir $DIR/$tdir
22488                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22489                         error "$LFS mkdir should return EEXIST if target exists"
22490                 rmdir $DIR/$tdir
22491         done
22492 }
22493 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22494
22495 test_230t()
22496 {
22497         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22498         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22499                 skip "Need MDS version at least 2.14.50"
22500
22501         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22502         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22503         $LFS project -p 1 -s $DIR/$tdir ||
22504                 error "set $tdir project id failed"
22505         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22506                 error "set subdir project id failed"
22507         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22508 }
22509 run_test 230t "migrate directory with project ID set"
22510
22511 test_230u()
22512 {
22513         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22514         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22515                 skip "Need MDS version at least 2.14.53"
22516
22517         local count
22518
22519         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22520         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22521         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22522         for i in $(seq 0 $((MDSCOUNT - 1))); do
22523                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22524                 echo "$count dirs migrated to MDT$i"
22525         done
22526         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22527         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22528 }
22529 run_test 230u "migrate directory by QOS"
22530
22531 test_230v()
22532 {
22533         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22534         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22535                 skip "Need MDS version at least 2.14.53"
22536
22537         local count
22538
22539         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22540         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22541         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22542         for i in $(seq 0 $((MDSCOUNT - 1))); do
22543                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22544                 echo "$count subdirs migrated to MDT$i"
22545                 (( i == 3 )) && (( count > 0 )) &&
22546                         error "subdir shouldn't be migrated to MDT3"
22547         done
22548         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22549         (( count == 3 )) || error "dirs migrated to $count MDTs"
22550 }
22551 run_test 230v "subdir migrated to the MDT where its parent is located"
22552
22553 test_230w() {
22554         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22555         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22556                 skip "Need MDS version at least 2.15.0"
22557
22558         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22559         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22560         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22561
22562         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22563                 error "migrate failed"
22564
22565         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22566                 error "$tdir stripe count mismatch"
22567
22568         for i in $(seq 0 9); do
22569                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22570                         error "d$i is striped"
22571         done
22572 }
22573 run_test 230w "non-recursive mode dir migration"
22574
22575 test_230x() {
22576         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22577         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22578                 skip "Need MDS version at least 2.15.0"
22579
22580         mkdir -p $DIR/$tdir || error "mkdir failed"
22581         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22582
22583         local mdt_name=$(mdtname_from_index 0)
22584         local low=$(do_facet mds2 $LCTL get_param -n \
22585                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22586         local high=$(do_facet mds2 $LCTL get_param -n \
22587                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22588         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22589         local maxage=$(do_facet mds2 $LCTL get_param -n \
22590                 osp.*$mdt_name-osp-MDT0001.maxage)
22591
22592         stack_trap "do_facet mds2 $LCTL set_param -n \
22593                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22594                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22595         stack_trap "do_facet mds2 $LCTL set_param -n \
22596                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22597
22598         do_facet mds2 $LCTL set_param -n \
22599                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22600         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22601         sleep 4
22602         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22603                 error "migrate $tdir should fail"
22604
22605         do_facet mds2 $LCTL set_param -n \
22606                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22607         do_facet mds2 $LCTL set_param -n \
22608                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22609         sleep 4
22610         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22611                 error "migrate failed"
22612         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22613                 error "$tdir stripe count mismatch"
22614 }
22615 run_test 230x "dir migration check space"
22616
22617 test_230y() {
22618         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22619         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22620                 skip "Need MDS version at least 2.15.55.45"
22621
22622         local pid
22623
22624         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22625         $LFS getdirstripe $DIR/$tdir
22626         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22627         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22628         pid=$!
22629         sleep 1
22630
22631         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22632         do_facet mds2 lctl set_param fail_loc=0x1802
22633
22634         wait $pid
22635         do_facet mds2 lctl set_param fail_loc=0
22636         $LFS getdirstripe $DIR/$tdir
22637         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22638         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22639 }
22640 run_test 230y "unlink dir with bad hash type"
22641
22642 test_230z() {
22643         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22644         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22645                 skip "Need MDS version at least 2.15.55.45"
22646
22647         local pid
22648
22649         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22650         $LFS getdirstripe $DIR/$tdir
22651         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22652         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22653         pid=$!
22654         sleep 1
22655
22656         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22657         do_facet mds2 lctl set_param fail_loc=0x1802
22658
22659         wait $pid
22660         do_facet mds2 lctl set_param fail_loc=0
22661         $LFS getdirstripe $DIR/$tdir
22662
22663         # resume migration
22664         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22665                 error "resume migration failed"
22666         $LFS getdirstripe $DIR/$tdir
22667         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22668                 error "migration is not finished"
22669 }
22670 run_test 230z "resume dir migration with bad hash type"
22671
22672 test_231a()
22673 {
22674         # For simplicity this test assumes that max_pages_per_rpc
22675         # is the same across all OSCs
22676         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22677         local bulk_size=$((max_pages * PAGE_SIZE))
22678         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22679                                        head -n 1)
22680
22681         mkdir -p $DIR/$tdir
22682         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22683                 error "failed to set stripe with -S ${brw_size}M option"
22684         stack_trap "rm -rf $DIR/$tdir"
22685
22686         # clear the OSC stats
22687         $LCTL set_param osc.*.stats=0 &>/dev/null
22688         stop_writeback
22689
22690         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22692                 oflag=direct &>/dev/null || error "dd failed"
22693
22694         sync; sleep 1; sync # just to be safe
22695         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22696         if [ x$nrpcs != "x1" ]; then
22697                 $LCTL get_param osc.*.stats
22698                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22699         fi
22700
22701         start_writeback
22702         # Drop the OSC cache, otherwise we will read from it
22703         cancel_lru_locks osc
22704
22705         # clear the OSC stats
22706         $LCTL set_param osc.*.stats=0 &>/dev/null
22707
22708         # Client reads $bulk_size.
22709         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22710                 iflag=direct &>/dev/null || error "dd failed"
22711
22712         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22713         if [ x$nrpcs != "x1" ]; then
22714                 $LCTL get_param osc.*.stats
22715                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22716         fi
22717 }
22718 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22719
22720 test_231b() {
22721         mkdir -p $DIR/$tdir
22722         stack_trap "rm -rf $DIR/$tdir"
22723         local i
22724         for i in {0..1023}; do
22725                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22726                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22727                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22728         done
22729         sync
22730 }
22731 run_test 231b "must not assert on fully utilized OST request buffer"
22732
22733 test_232a() {
22734         mkdir -p $DIR/$tdir
22735         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22736
22737         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22738         do_facet ost1 $LCTL set_param fail_loc=0x31c
22739
22740         # ignore dd failure
22741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22742         stack_trap "rm -f $DIR/$tdir/$tfile"
22743
22744         do_facet ost1 $LCTL set_param fail_loc=0
22745         umount_client $MOUNT || error "umount failed"
22746         mount_client $MOUNT || error "mount failed"
22747         stop ost1 || error "cannot stop ost1"
22748         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22749 }
22750 run_test 232a "failed lock should not block umount"
22751
22752 test_232b() {
22753         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22754                 skip "Need MDS version at least 2.10.58"
22755
22756         mkdir -p $DIR/$tdir
22757         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22758         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22759         stack_trap "rm -f $DIR/$tdir/$tfile"
22760         sync
22761         cancel_lru_locks osc
22762
22763         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22764         do_facet ost1 $LCTL set_param fail_loc=0x31c
22765
22766         # ignore failure
22767         $LFS data_version $DIR/$tdir/$tfile || true
22768
22769         do_facet ost1 $LCTL set_param fail_loc=0
22770         umount_client $MOUNT || error "umount failed"
22771         mount_client $MOUNT || error "mount failed"
22772         stop ost1 || error "cannot stop ost1"
22773         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22774 }
22775 run_test 232b "failed data version lock should not block umount"
22776
22777 test_233a() {
22778         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22779                 skip "Need MDS version at least 2.3.64"
22780         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22781
22782         local fid=$($LFS path2fid $MOUNT)
22783
22784         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22785                 error "cannot access $MOUNT using its FID '$fid'"
22786 }
22787 run_test 233a "checking that OBF of the FS root succeeds"
22788
22789 test_233b() {
22790         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22791                 skip "Need MDS version at least 2.5.90"
22792         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22793
22794         local fid=$($LFS path2fid $MOUNT/.lustre)
22795
22796         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22797                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22798
22799         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22800         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22801                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22802 }
22803 run_test 233b "checking that OBF of the FS .lustre succeeds"
22804
22805 test_234() {
22806         local p="$TMP/sanityN-$TESTNAME.parameters"
22807         save_lustre_params client "llite.*.xattr_cache" > $p
22808         lctl set_param llite.*.xattr_cache 1 ||
22809                 skip_env "xattr cache is not supported"
22810
22811         mkdir -p $DIR/$tdir || error "mkdir failed"
22812         touch $DIR/$tdir/$tfile || error "touch failed"
22813         # OBD_FAIL_LLITE_XATTR_ENOMEM
22814         $LCTL set_param fail_loc=0x1405
22815         getfattr -n user.attr $DIR/$tdir/$tfile &&
22816                 error "getfattr should have failed with ENOMEM"
22817         $LCTL set_param fail_loc=0x0
22818         rm -rf $DIR/$tdir
22819
22820         restore_lustre_params < $p
22821         rm -f $p
22822 }
22823 run_test 234 "xattr cache should not crash on ENOMEM"
22824
22825 test_235() {
22826         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22827                 skip "Need MDS version at least 2.4.52"
22828
22829         flock_deadlock $DIR/$tfile
22830         local RC=$?
22831         case $RC in
22832                 0)
22833                 ;;
22834                 124) error "process hangs on a deadlock"
22835                 ;;
22836                 *) error "error executing flock_deadlock $DIR/$tfile"
22837                 ;;
22838         esac
22839 }
22840 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22841
22842 #LU-2935
22843 test_236() {
22844         check_swap_layouts_support
22845
22846         local ref1=/etc/passwd
22847         local ref2=/etc/group
22848         local file1=$DIR/$tdir/f1
22849         local file2=$DIR/$tdir/f2
22850
22851         test_mkdir -c1 $DIR/$tdir
22852         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22853         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22854         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22855         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22856         local fd=$(free_fd)
22857         local cmd="exec $fd<>$file2"
22858         eval $cmd
22859         rm $file2
22860         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22861                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22862         cmd="exec $fd>&-"
22863         eval $cmd
22864         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22865
22866         #cleanup
22867         rm -rf $DIR/$tdir
22868 }
22869 run_test 236 "Layout swap on open unlinked file"
22870
22871 # LU-4659 linkea consistency
22872 test_238() {
22873         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22874                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22875                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22876                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22877
22878         touch $DIR/$tfile
22879         ln $DIR/$tfile $DIR/$tfile.lnk
22880         touch $DIR/$tfile.new
22881         mv $DIR/$tfile.new $DIR/$tfile
22882         local fid1=$($LFS path2fid $DIR/$tfile)
22883         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22884         local path1=$($LFS fid2path $FSNAME "$fid1")
22885         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22886         local path2=$($LFS fid2path $FSNAME "$fid2")
22887         [ $tfile.lnk == $path2 ] ||
22888                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22889         rm -f $DIR/$tfile*
22890 }
22891 run_test 238 "Verify linkea consistency"
22892
22893 test_239A() { # was test_239
22894         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22895                 skip "Need MDS version at least 2.5.60"
22896
22897         local list=$(comma_list $(mdts_nodes))
22898
22899         mkdir -p $DIR/$tdir
22900         createmany -o $DIR/$tdir/f- 5000
22901         unlinkmany $DIR/$tdir/f- 5000
22902         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22903                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22904         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22905                         osp.*MDT*.sync_in_flight" | calc_sum)
22906         [ "$changes" -eq 0 ] || error "$changes not synced"
22907 }
22908 run_test 239A "osp_sync test"
22909
22910 test_239a() { #LU-5297
22911         remote_mds_nodsh && skip "remote MDS with nodsh"
22912
22913         touch $DIR/$tfile
22914         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22915         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22916         chgrp $RUNAS_GID $DIR/$tfile
22917         wait_delete_completed
22918 }
22919 run_test 239a "process invalid osp sync record correctly"
22920
22921 test_239b() { #LU-5297
22922         remote_mds_nodsh && skip "remote MDS with nodsh"
22923
22924         touch $DIR/$tfile1
22925         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22926         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22927         chgrp $RUNAS_GID $DIR/$tfile1
22928         wait_delete_completed
22929         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22930         touch $DIR/$tfile2
22931         chgrp $RUNAS_GID $DIR/$tfile2
22932         wait_delete_completed
22933 }
22934 run_test 239b "process osp sync record with ENOMEM error correctly"
22935
22936 test_240() {
22937         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22938         remote_mds_nodsh && skip "remote MDS with nodsh"
22939
22940         mkdir -p $DIR/$tdir
22941
22942         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22943                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22944         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22945                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22946
22947         umount_client $MOUNT || error "umount failed"
22948         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22949         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22950         mount_client $MOUNT || error "failed to mount client"
22951
22952         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22953         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22954 }
22955 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22956
22957 test_241_bio() {
22958         local count=$1
22959         local bsize=$2
22960
22961         for LOOP in $(seq $count); do
22962                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22963                 cancel_lru_locks $OSC || true
22964         done
22965 }
22966
22967 test_241_dio() {
22968         local count=$1
22969         local bsize=$2
22970
22971         for LOOP in $(seq $1); do
22972                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22973                         2>/dev/null
22974         done
22975 }
22976
22977 test_241a() { # was test_241
22978         local bsize=$PAGE_SIZE
22979
22980         (( bsize < 40960 )) && bsize=40960
22981         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22982         ls -la $DIR/$tfile
22983         cancel_lru_locks $OSC
22984         test_241_bio 1000 $bsize &
22985         PID=$!
22986         test_241_dio 1000 $bsize
22987         wait $PID
22988 }
22989 run_test 241a "bio vs dio"
22990
22991 test_241b() {
22992         local bsize=$PAGE_SIZE
22993
22994         (( bsize < 40960 )) && bsize=40960
22995         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22996         ls -la $DIR/$tfile
22997         test_241_dio 1000 $bsize &
22998         PID=$!
22999         test_241_dio 1000 $bsize
23000         wait $PID
23001 }
23002 run_test 241b "dio vs dio"
23003
23004 test_242() {
23005         remote_mds_nodsh && skip "remote MDS with nodsh"
23006
23007         mkdir_on_mdt0 $DIR/$tdir
23008         touch $DIR/$tdir/$tfile
23009
23010         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23011         do_facet mds1 lctl set_param fail_loc=0x105
23012         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23013
23014         do_facet mds1 lctl set_param fail_loc=0
23015         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23016 }
23017 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23018
23019 test_243()
23020 {
23021         test_mkdir $DIR/$tdir
23022         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23023 }
23024 run_test 243 "various group lock tests"
23025
23026 test_244a()
23027 {
23028         test_mkdir $DIR/$tdir
23029         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23030         sendfile_grouplock $DIR/$tdir/$tfile || \
23031                 error "sendfile+grouplock failed"
23032         rm -rf $DIR/$tdir
23033 }
23034 run_test 244a "sendfile with group lock tests"
23035
23036 test_244b()
23037 {
23038         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23039
23040         local threads=50
23041         local size=$((1024*1024))
23042
23043         test_mkdir $DIR/$tdir
23044         for i in $(seq 1 $threads); do
23045                 local file=$DIR/$tdir/file_$((i / 10))
23046                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23047                 local pids[$i]=$!
23048         done
23049         for i in $(seq 1 $threads); do
23050                 wait ${pids[$i]}
23051         done
23052 }
23053 run_test 244b "multi-threaded write with group lock"
23054
23055 test_245a() {
23056         local flagname="multi_mod_rpcs"
23057         local connect_data_name="max_mod_rpcs"
23058         local out
23059
23060         # check if multiple modify RPCs flag is set
23061         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23062                 grep "connect_flags:")
23063         echo "$out"
23064
23065         echo "$out" | grep -qw $flagname
23066         if [ $? -ne 0 ]; then
23067                 echo "connect flag $flagname is not set"
23068                 return
23069         fi
23070
23071         # check if multiple modify RPCs data is set
23072         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23073         echo "$out"
23074
23075         echo "$out" | grep -qw $connect_data_name ||
23076                 error "import should have connect data $connect_data_name"
23077 }
23078 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23079
23080 test_245b() {
23081         local flagname="multi_mod_rpcs"
23082         local connect_data_name="max_mod_rpcs"
23083         local out
23084
23085         remote_mds_nodsh && skip "remote MDS with nodsh"
23086         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23087
23088         # check if multiple modify RPCs flag is set
23089         out=$(do_facet mds1 \
23090               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23091               grep "connect_flags:")
23092         echo "$out"
23093
23094         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23095
23096         # check if multiple modify RPCs data is set
23097         out=$(do_facet mds1 \
23098               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23099
23100         [[ "$out" =~ $connect_data_name ]] ||
23101                 {
23102                         echo "$out"
23103                         error "missing connect data $connect_data_name"
23104                 }
23105 }
23106 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23107
23108 cleanup_247() {
23109         local submount=$1
23110
23111         trap 0
23112         umount_client $submount
23113         rmdir $submount
23114 }
23115
23116 test_247a() {
23117         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23118                 grep -q subtree ||
23119                 skip_env "Fileset feature is not supported"
23120
23121         local submount=${MOUNT}_$tdir
23122
23123         mkdir $MOUNT/$tdir
23124         mkdir -p $submount || error "mkdir $submount failed"
23125         FILESET="$FILESET/$tdir" mount_client $submount ||
23126                 error "mount $submount failed"
23127         trap "cleanup_247 $submount" EXIT
23128         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23129         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23130                 error "read $MOUNT/$tdir/$tfile failed"
23131         cleanup_247 $submount
23132 }
23133 run_test 247a "mount subdir as fileset"
23134
23135 test_247b() {
23136         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23137                 skip_env "Fileset feature is not supported"
23138
23139         local submount=${MOUNT}_$tdir
23140
23141         rm -rf $MOUNT/$tdir
23142         mkdir -p $submount || error "mkdir $submount failed"
23143         SKIP_FILESET=1
23144         FILESET="$FILESET/$tdir" mount_client $submount &&
23145                 error "mount $submount should fail"
23146         rmdir $submount
23147 }
23148 run_test 247b "mount subdir that dose not exist"
23149
23150 test_247c() {
23151         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23152                 skip_env "Fileset feature is not supported"
23153
23154         local submount=${MOUNT}_$tdir
23155
23156         mkdir -p $MOUNT/$tdir/dir1
23157         mkdir -p $submount || error "mkdir $submount failed"
23158         trap "cleanup_247 $submount" EXIT
23159         FILESET="$FILESET/$tdir" mount_client $submount ||
23160                 error "mount $submount failed"
23161         local fid=$($LFS path2fid $MOUNT/)
23162         $LFS fid2path $submount $fid && error "fid2path should fail"
23163         cleanup_247 $submount
23164 }
23165 run_test 247c "running fid2path outside subdirectory root"
23166
23167 test_247d() {
23168         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23169                 skip "Fileset feature is not supported"
23170
23171         local submount=${MOUNT}_$tdir
23172
23173         mkdir -p $MOUNT/$tdir/dir1
23174         mkdir -p $submount || error "mkdir $submount failed"
23175         FILESET="$FILESET/$tdir" mount_client $submount ||
23176                 error "mount $submount failed"
23177         trap "cleanup_247 $submount" EXIT
23178
23179         local td=$submount/dir1
23180         local fid=$($LFS path2fid $td)
23181         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23182
23183         # check that we get the same pathname back
23184         local rootpath
23185         local found
23186         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23187                 echo "$rootpath $fid"
23188                 found=$($LFS fid2path $rootpath "$fid")
23189                 [ -n "$found" ] || error "fid2path should succeed"
23190                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23191         done
23192         # check wrong root path format
23193         rootpath=$submount"_wrong"
23194         found=$($LFS fid2path $rootpath "$fid")
23195         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23196
23197         cleanup_247 $submount
23198 }
23199 run_test 247d "running fid2path inside subdirectory root"
23200
23201 # LU-8037
23202 test_247e() {
23203         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23204                 grep -q subtree ||
23205                 skip "Fileset feature is not supported"
23206
23207         local submount=${MOUNT}_$tdir
23208
23209         mkdir $MOUNT/$tdir
23210         mkdir -p $submount || error "mkdir $submount failed"
23211         FILESET="$FILESET/.." mount_client $submount &&
23212                 error "mount $submount should fail"
23213         rmdir $submount
23214 }
23215 run_test 247e "mount .. as fileset"
23216
23217 test_247f() {
23218         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23219         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23220                 skip "Need at least version 2.14.50.162"
23221         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23222                 skip "Fileset feature is not supported"
23223
23224         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23225         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23226                 error "mkdir remote failed"
23227         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23228                 error "mkdir remote/subdir failed"
23229         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23230                 error "mkdir striped failed"
23231         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23232
23233         local submount=${MOUNT}_$tdir
23234
23235         mkdir -p $submount || error "mkdir $submount failed"
23236         stack_trap "rmdir $submount"
23237
23238         local dir
23239         local fileset=$FILESET
23240         local mdts=$(comma_list $(mdts_nodes))
23241
23242         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23243         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23244                 $tdir/striped/subdir $tdir/striped/.; do
23245                 FILESET="$fileset/$dir" mount_client $submount ||
23246                         error "mount $dir failed"
23247                 umount_client $submount
23248         done
23249 }
23250 run_test 247f "mount striped or remote directory as fileset"
23251
23252 test_subdir_mount_lock()
23253 {
23254         local testdir=$1
23255         local submount=${MOUNT}_$(basename $testdir)
23256
23257         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23258
23259         mkdir -p $submount || error "mkdir $submount failed"
23260         stack_trap "rmdir $submount"
23261
23262         FILESET="$fileset/$testdir" mount_client $submount ||
23263                 error "mount $FILESET failed"
23264         stack_trap "umount $submount"
23265
23266         local mdts=$(comma_list $(mdts_nodes))
23267
23268         local nrpcs
23269
23270         stat $submount > /dev/null || error "stat $submount failed"
23271         cancel_lru_locks $MDC
23272         stat $submount > /dev/null || error "stat $submount failed"
23273         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23274         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23275         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23276         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23277                 awk '/getattr/ {sum += $2} END {print sum}')
23278
23279         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23280 }
23281
23282 test_247g() {
23283         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23284
23285         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23286                 error "mkdir $tdir failed"
23287         test_subdir_mount_lock $tdir
23288 }
23289 run_test 247g "striped directory submount revalidate ROOT from cache"
23290
23291 test_247h() {
23292         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23293         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23294                 skip "Need MDS version at least 2.15.51"
23295
23296         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23297         test_subdir_mount_lock $tdir
23298         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23299         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23300                 error "mkdir $tdir.1 failed"
23301         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23302 }
23303 run_test 247h "remote directory submount revalidate ROOT from cache"
23304
23305 test_248a() {
23306         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23307         [ -z "$fast_read_sav" ] && skip "no fast read support"
23308
23309         # create a large file for fast read verification
23310         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23311
23312         # make sure the file is created correctly
23313         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23314                 { rm -f $DIR/$tfile; skip "file creation error"; }
23315
23316         echo "Test 1: verify that fast read is 4 times faster on cache read"
23317
23318         # small read with fast read enabled
23319         $LCTL set_param -n llite.*.fast_read=1
23320         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23321                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23322                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23323         # small read with fast read disabled
23324         $LCTL set_param -n llite.*.fast_read=0
23325         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23326                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23327                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23328
23329         # verify that fast read is 4 times faster for cache read
23330         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23331                 error_not_in_vm "fast read was not 4 times faster: " \
23332                            "$t_fast vs $t_slow"
23333
23334         echo "Test 2: verify the performance between big and small read"
23335         $LCTL set_param -n llite.*.fast_read=1
23336
23337         # 1k non-cache read
23338         cancel_lru_locks osc
23339         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23340                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23341                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23342
23343         # 1M non-cache read
23344         cancel_lru_locks osc
23345         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23346                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23347                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23348
23349         # verify that big IO is not 4 times faster than small IO
23350         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23351                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23352
23353         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23354         rm -f $DIR/$tfile
23355 }
23356 run_test 248a "fast read verification"
23357
23358 test_248b() {
23359         # Default short_io_bytes=16384, try both smaller and larger sizes.
23360         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23361         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23362         echo "bs=53248 count=113 normal buffered write"
23363         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23364                 error "dd of initial data file failed"
23365         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23366
23367         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23368         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23369                 error "dd with sync normal writes failed"
23370         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23371
23372         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23373         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23374                 error "dd with sync small writes failed"
23375         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23376
23377         cancel_lru_locks osc
23378
23379         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23380         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23381         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23382         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23383                 iflag=direct || error "dd with O_DIRECT small read failed"
23384         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23385         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23386                 error "compare $TMP/$tfile.1 failed"
23387
23388         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23389         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23390
23391         # just to see what the maximum tunable value is, and test parsing
23392         echo "test invalid parameter 2MB"
23393         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23394                 error "too-large short_io_bytes allowed"
23395         echo "test maximum parameter 512KB"
23396         # if we can set a larger short_io_bytes, run test regardless of version
23397         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23398                 # older clients may not allow setting it this large, that's OK
23399                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23400                         skip "Need at least client version 2.13.50"
23401                 error "medium short_io_bytes failed"
23402         fi
23403         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23404         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23405
23406         echo "test large parameter 64KB"
23407         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23408         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23409
23410         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23411         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23412                 error "dd with sync large writes failed"
23413         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23414
23415         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23416         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23417         num=$((113 * 4096 / PAGE_SIZE))
23418         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23419         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23420                 error "dd with O_DIRECT large writes failed"
23421         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23422                 error "compare $DIR/$tfile.3 failed"
23423
23424         cancel_lru_locks osc
23425
23426         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23427         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23428                 error "dd with O_DIRECT large read failed"
23429         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23430                 error "compare $TMP/$tfile.2 failed"
23431
23432         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23433         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23434                 error "dd with O_DIRECT large read failed"
23435         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23436                 error "compare $TMP/$tfile.3 failed"
23437 }
23438 run_test 248b "test short_io read and write for both small and large sizes"
23439
23440 test_249() { # LU-7890
23441         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23442                 skip "Need at least version 2.8.54"
23443
23444         rm -f $DIR/$tfile
23445         $LFS setstripe -c 1 $DIR/$tfile
23446         # Offset 2T == 4k * 512M
23447         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23448                 error "dd to 2T offset failed"
23449 }
23450 run_test 249 "Write above 2T file size"
23451
23452 test_250() {
23453         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23454          && skip "no 16TB file size limit on ZFS"
23455
23456         $LFS setstripe -c 1 $DIR/$tfile
23457         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23458         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23459         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23460         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23461                 conv=notrunc,fsync && error "append succeeded"
23462         return 0
23463 }
23464 run_test 250 "Write above 16T limit"
23465
23466 test_251() {
23467         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23468
23469         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23470         #Skip once - writing the first stripe will succeed
23471         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23472         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23473                 error "short write happened"
23474
23475         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23476         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23477                 error "short read happened"
23478
23479         rm -f $DIR/$tfile
23480 }
23481 run_test 251 "Handling short read and write correctly"
23482
23483 test_252() {
23484         remote_mds_nodsh && skip "remote MDS with nodsh"
23485         remote_ost_nodsh && skip "remote OST with nodsh"
23486         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23487                 skip_env "ldiskfs only test"
23488         fi
23489
23490         local tgt
23491         local dev
23492         local out
23493         local uuid
23494         local num
23495         local gen
23496
23497         # check lr_reader on OST0000
23498         tgt=ost1
23499         dev=$(facet_device $tgt)
23500         out=$(do_facet $tgt $LR_READER $dev)
23501         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23502         echo "$out"
23503         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23504         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23505                 error "Invalid uuid returned by $LR_READER on target $tgt"
23506         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23507
23508         # check lr_reader -c on MDT0000
23509         tgt=mds1
23510         dev=$(facet_device $tgt)
23511         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23512                 skip "$LR_READER does not support additional options"
23513         fi
23514         out=$(do_facet $tgt $LR_READER -c $dev)
23515         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23516         echo "$out"
23517         num=$(echo "$out" | grep -c "mdtlov")
23518         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23519                 error "Invalid number of mdtlov clients returned by $LR_READER"
23520         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23521
23522         # check lr_reader -cr on MDT0000
23523         out=$(do_facet $tgt $LR_READER -cr $dev)
23524         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23525         echo "$out"
23526         echo "$out" | grep -q "^reply_data:$" ||
23527                 error "$LR_READER should have returned 'reply_data' section"
23528         num=$(echo "$out" | grep -c "client_generation")
23529         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23530 }
23531 run_test 252 "check lr_reader tool"
23532
23533 test_253() {
23534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23535         remote_mds_nodsh && skip "remote MDS with nodsh"
23536         remote_mgs_nodsh && skip "remote MGS with nodsh"
23537
23538         local ostidx=0
23539         local rc=0
23540         local ost_name=$(ostname_from_index $ostidx)
23541
23542         # on the mdt's osc
23543         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23544         do_facet $SINGLEMDS $LCTL get_param -n \
23545                 osp.$mdtosc_proc1.reserved_mb_high ||
23546                 skip  "remote MDS does not support reserved_mb_high"
23547
23548         rm -rf $DIR/$tdir
23549         wait_mds_ost_sync
23550         wait_delete_completed
23551         mkdir $DIR/$tdir
23552         stack_trap "rm -rf $DIR/$tdir"
23553
23554         pool_add $TESTNAME || error "Pool creation failed"
23555         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23556
23557         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23558                 error "Setstripe failed"
23559
23560         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23561
23562         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23563                     grep "watermarks")
23564         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23565
23566         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23567                         osp.$mdtosc_proc1.prealloc_status)
23568         echo "prealloc_status $oa_status"
23569
23570         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23571                 error "File creation should fail"
23572
23573         #object allocation was stopped, but we still able to append files
23574         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23575                 oflag=append || error "Append failed"
23576
23577         rm -f $DIR/$tdir/$tfile.0
23578
23579         # For this test, we want to delete the files we created to go out of
23580         # space but leave the watermark, so we remain nearly out of space
23581         ost_watermarks_enospc_delete_files $tfile $ostidx
23582
23583         wait_delete_completed
23584
23585         sleep_maxage
23586
23587         for i in $(seq 10 12); do
23588                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23589                         2>/dev/null || error "File creation failed after rm"
23590         done
23591
23592         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23593                         osp.$mdtosc_proc1.prealloc_status)
23594         echo "prealloc_status $oa_status"
23595
23596         if (( oa_status != 0 )); then
23597                 error "Object allocation still disable after rm"
23598         fi
23599 }
23600 run_test 253 "Check object allocation limit"
23601
23602 test_254() {
23603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23604         remote_mds_nodsh && skip "remote MDS with nodsh"
23605
23606         local mdt=$(facet_svc $SINGLEMDS)
23607
23608         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23609                 skip "MDS does not support changelog_size"
23610
23611         local cl_user
23612
23613         changelog_register || error "changelog_register failed"
23614
23615         changelog_clear 0 || error "changelog_clear failed"
23616
23617         local size1=$(do_facet $SINGLEMDS \
23618                       $LCTL get_param -n mdd.$mdt.changelog_size)
23619         echo "Changelog size $size1"
23620
23621         rm -rf $DIR/$tdir
23622         $LFS mkdir -i 0 $DIR/$tdir
23623         # change something
23624         mkdir -p $DIR/$tdir/pics/2008/zachy
23625         touch $DIR/$tdir/pics/2008/zachy/timestamp
23626         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23627         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23628         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23629         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23630         rm $DIR/$tdir/pics/desktop.jpg
23631
23632         local size2=$(do_facet $SINGLEMDS \
23633                       $LCTL get_param -n mdd.$mdt.changelog_size)
23634         echo "Changelog size after work $size2"
23635
23636         (( $size2 > $size1 )) ||
23637                 error "new Changelog size=$size2 less than old size=$size1"
23638 }
23639 run_test 254 "Check changelog size"
23640
23641 ladvise_no_type()
23642 {
23643         local type=$1
23644         local file=$2
23645
23646         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23647                 awk -F: '{print $2}' | grep $type > /dev/null
23648         if [ $? -ne 0 ]; then
23649                 return 0
23650         fi
23651         return 1
23652 }
23653
23654 ladvise_no_ioctl()
23655 {
23656         local file=$1
23657
23658         lfs ladvise -a willread $file > /dev/null 2>&1
23659         if [ $? -eq 0 ]; then
23660                 return 1
23661         fi
23662
23663         lfs ladvise -a willread $file 2>&1 |
23664                 grep "Inappropriate ioctl for device" > /dev/null
23665         if [ $? -eq 0 ]; then
23666                 return 0
23667         fi
23668         return 1
23669 }
23670
23671 percent() {
23672         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23673 }
23674
23675 # run a random read IO workload
23676 # usage: random_read_iops <filename> <filesize> <iosize>
23677 random_read_iops() {
23678         local file=$1
23679         local fsize=$2
23680         local iosize=${3:-4096}
23681
23682         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23683                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23684 }
23685
23686 drop_file_oss_cache() {
23687         local file="$1"
23688         local nodes="$2"
23689
23690         $LFS ladvise -a dontneed $file 2>/dev/null ||
23691                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23692 }
23693
23694 ladvise_willread_performance()
23695 {
23696         local repeat=10
23697         local average_origin=0
23698         local average_cache=0
23699         local average_ladvise=0
23700
23701         for ((i = 1; i <= $repeat; i++)); do
23702                 echo "Iter $i/$repeat: reading without willread hint"
23703                 cancel_lru_locks osc
23704                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23705                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23706                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23707                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23708
23709                 cancel_lru_locks osc
23710                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23711                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23712                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23713
23714                 cancel_lru_locks osc
23715                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23716                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23717                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23718                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23719                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23720         done
23721         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23722         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23723         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23724
23725         speedup_cache=$(percent $average_cache $average_origin)
23726         speedup_ladvise=$(percent $average_ladvise $average_origin)
23727
23728         echo "Average uncached read: $average_origin"
23729         echo "Average speedup with OSS cached read: " \
23730                 "$average_cache = +$speedup_cache%"
23731         echo "Average speedup with ladvise willread: " \
23732                 "$average_ladvise = +$speedup_ladvise%"
23733
23734         local lowest_speedup=20
23735         if (( ${average_cache%.*} < $lowest_speedup )); then
23736                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23737                      " got $average_cache%. Skipping ladvise willread check."
23738                 return 0
23739         fi
23740
23741         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23742         # it is still good to run until then to exercise 'ladvise willread'
23743         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23744                 [ "$ost1_FSTYPE" = "zfs" ] &&
23745                 echo "osd-zfs does not support dontneed or drop_caches" &&
23746                 return 0
23747
23748         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23749         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23750                 error_not_in_vm "Speedup with willread is less than " \
23751                         "$lowest_speedup%, got $average_ladvise%"
23752 }
23753
23754 test_255a() {
23755         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23756                 skip "lustre < 2.8.54 does not support ladvise "
23757         remote_ost_nodsh && skip "remote OST with nodsh"
23758
23759         stack_trap "rm -f $DIR/$tfile"
23760         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23761
23762         ladvise_no_type willread $DIR/$tfile &&
23763                 skip "willread ladvise is not supported"
23764
23765         ladvise_no_ioctl $DIR/$tfile &&
23766                 skip "ladvise ioctl is not supported"
23767
23768         local size_mb=100
23769         local size=$((size_mb * 1048576))
23770         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23771                 error "dd to $DIR/$tfile failed"
23772
23773         lfs ladvise -a willread $DIR/$tfile ||
23774                 error "Ladvise failed with no range argument"
23775
23776         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23777                 error "Ladvise failed with no -l or -e argument"
23778
23779         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23780                 error "Ladvise failed with only -e argument"
23781
23782         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23783                 error "Ladvise failed with only -l argument"
23784
23785         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23786                 error "End offset should not be smaller than start offset"
23787
23788         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23789                 error "End offset should not be equal to start offset"
23790
23791         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23792                 error "Ladvise failed with overflowing -s argument"
23793
23794         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23795                 error "Ladvise failed with overflowing -e argument"
23796
23797         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23798                 error "Ladvise failed with overflowing -l argument"
23799
23800         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23801                 error "Ladvise succeeded with conflicting -l and -e arguments"
23802
23803         echo "Synchronous ladvise should wait"
23804         local delay=8
23805 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23806         do_nodes $(comma_list $(osts_nodes)) \
23807                 $LCTL set_param fail_val=$delay fail_loc=0x237
23808         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23809                 $LCTL set_param fail_loc=0"
23810
23811         local start_ts=$SECONDS
23812         lfs ladvise -a willread $DIR/$tfile ||
23813                 error "Ladvise failed with no range argument"
23814         local end_ts=$SECONDS
23815         local inteval_ts=$((end_ts - start_ts))
23816
23817         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23818                 error "Synchronous advice didn't wait reply"
23819         fi
23820
23821         echo "Asynchronous ladvise shouldn't wait"
23822         local start_ts=$SECONDS
23823         lfs ladvise -a willread -b $DIR/$tfile ||
23824                 error "Ladvise failed with no range argument"
23825         local end_ts=$SECONDS
23826         local inteval_ts=$((end_ts - start_ts))
23827
23828         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23829                 error "Asynchronous advice blocked"
23830         fi
23831
23832         ladvise_willread_performance
23833 }
23834 run_test 255a "check 'lfs ladvise -a willread'"
23835
23836 facet_meminfo() {
23837         local facet=$1
23838         local info=$2
23839
23840         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23841 }
23842
23843 test_255b() {
23844         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23845                 skip "lustre < 2.8.54 does not support ladvise "
23846         remote_ost_nodsh && skip "remote OST with nodsh"
23847
23848         stack_trap "rm -f $DIR/$tfile"
23849         lfs setstripe -c 1 -i 0 $DIR/$tfile
23850
23851         ladvise_no_type dontneed $DIR/$tfile &&
23852                 skip "dontneed ladvise is not supported"
23853
23854         ladvise_no_ioctl $DIR/$tfile &&
23855                 skip "ladvise ioctl is not supported"
23856
23857         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23858                 [ "$ost1_FSTYPE" = "zfs" ] &&
23859                 skip "zfs-osd does not support 'ladvise dontneed'"
23860
23861         local size_mb=100
23862         local size=$((size_mb * 1048576))
23863         # In order to prevent disturbance of other processes, only check 3/4
23864         # of the memory usage
23865         local kibibytes=$((size_mb * 1024 * 3 / 4))
23866
23867         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23868                 error "dd to $DIR/$tfile failed"
23869
23870         #force write to complete before dropping OST cache & checking memory
23871         sync
23872
23873         local total=$(facet_meminfo ost1 MemTotal)
23874         echo "Total memory: $total KiB"
23875
23876         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23877         local before_read=$(facet_meminfo ost1 Cached)
23878         echo "Cache used before read: $before_read KiB"
23879
23880         lfs ladvise -a willread $DIR/$tfile ||
23881                 error "Ladvise willread failed"
23882         local after_read=$(facet_meminfo ost1 Cached)
23883         echo "Cache used after read: $after_read KiB"
23884
23885         lfs ladvise -a dontneed $DIR/$tfile ||
23886                 error "Ladvise dontneed again failed"
23887         local no_read=$(facet_meminfo ost1 Cached)
23888         echo "Cache used after dontneed ladvise: $no_read KiB"
23889
23890         if [ $total -lt $((before_read + kibibytes)) ]; then
23891                 echo "Memory is too small, abort checking"
23892                 return 0
23893         fi
23894
23895         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23896                 error "Ladvise willread should use more memory" \
23897                         "than $kibibytes KiB"
23898         fi
23899
23900         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23901                 error "Ladvise dontneed should release more memory" \
23902                         "than $kibibytes KiB"
23903         fi
23904 }
23905 run_test 255b "check 'lfs ladvise -a dontneed'"
23906
23907 test_255c() {
23908         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23909                 skip "lustre < 2.10.50 does not support lockahead"
23910
23911         local ost1_imp=$(get_osc_import_name client ost1)
23912         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23913                          cut -d'.' -f2)
23914         local count
23915         local new_count
23916         local difference
23917         local i
23918         local rc
23919
23920         test_mkdir -p $DIR/$tdir
23921         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23922
23923         #test 10 returns only success/failure
23924         i=10
23925         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23926         rc=$?
23927         if [ $rc -eq 255 ]; then
23928                 error "Ladvise test${i} failed, ${rc}"
23929         fi
23930
23931         #test 11 counts lock enqueue requests, all others count new locks
23932         i=11
23933         count=$(do_facet ost1 \
23934                 $LCTL get_param -n ost.OSS.ost.stats)
23935         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23936
23937         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23938         rc=$?
23939         if [ $rc -eq 255 ]; then
23940                 error "Ladvise test${i} failed, ${rc}"
23941         fi
23942
23943         new_count=$(do_facet ost1 \
23944                 $LCTL get_param -n ost.OSS.ost.stats)
23945         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23946                    awk '{ print $2 }')
23947
23948         difference="$((new_count - count))"
23949         if [ $difference -ne $rc ]; then
23950                 error "Ladvise test${i}, bad enqueue count, returned " \
23951                       "${rc}, actual ${difference}"
23952         fi
23953
23954         for i in $(seq 12 21); do
23955                 # If we do not do this, we run the risk of having too many
23956                 # locks and starting lock cancellation while we are checking
23957                 # lock counts.
23958                 cancel_lru_locks osc
23959
23960                 count=$($LCTL get_param -n \
23961                        ldlm.namespaces.$imp_name.lock_unused_count)
23962
23963                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23964                 rc=$?
23965                 if [ $rc -eq 255 ]; then
23966                         error "Ladvise test ${i} failed, ${rc}"
23967                 fi
23968
23969                 new_count=$($LCTL get_param -n \
23970                        ldlm.namespaces.$imp_name.lock_unused_count)
23971                 difference="$((new_count - count))"
23972
23973                 # Test 15 output is divided by 100 to map down to valid return
23974                 if [ $i -eq 15 ]; then
23975                         rc="$((rc * 100))"
23976                 fi
23977
23978                 if [ $difference -ne $rc ]; then
23979                         error "Ladvise test ${i}, bad lock count, returned " \
23980                               "${rc}, actual ${difference}"
23981                 fi
23982         done
23983
23984         #test 22 returns only success/failure
23985         i=22
23986         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23987         rc=$?
23988         if [ $rc -eq 255 ]; then
23989                 error "Ladvise test${i} failed, ${rc}"
23990         fi
23991 }
23992 run_test 255c "suite of ladvise lockahead tests"
23993
23994 test_256() {
23995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23996         remote_mds_nodsh && skip "remote MDS with nodsh"
23997         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23998         changelog_users $SINGLEMDS | grep "^cl" &&
23999                 skip "active changelog user"
24000
24001         local cl_user
24002         local cat_sl
24003         local mdt_dev
24004
24005         mdt_dev=$(facet_device $SINGLEMDS)
24006         echo $mdt_dev
24007
24008         changelog_register || error "changelog_register failed"
24009
24010         rm -rf $DIR/$tdir
24011         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24012
24013         changelog_clear 0 || error "changelog_clear failed"
24014
24015         # change something
24016         touch $DIR/$tdir/{1..10}
24017
24018         # stop the MDT
24019         stop $SINGLEMDS || error "Fail to stop MDT"
24020
24021         # remount the MDT
24022         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24023                 error "Fail to start MDT"
24024
24025         #after mount new plainllog is used
24026         touch $DIR/$tdir/{11..19}
24027         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24028         stack_trap "rm -f $tmpfile"
24029         cat_sl=$(do_facet $SINGLEMDS "sync; \
24030                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24031                  llog_reader $tmpfile | grep -c type=1064553b")
24032         do_facet $SINGLEMDS llog_reader $tmpfile
24033
24034         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24035
24036         changelog_clear 0 || error "changelog_clear failed"
24037
24038         cat_sl=$(do_facet $SINGLEMDS "sync; \
24039                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24040                  llog_reader $tmpfile | grep -c type=1064553b")
24041
24042         if (( cat_sl == 2 )); then
24043                 error "Empty plain llog was not deleted from changelog catalog"
24044         elif (( cat_sl != 1 )); then
24045                 error "Active plain llog shouldn't be deleted from catalog"
24046         fi
24047 }
24048 run_test 256 "Check llog delete for empty and not full state"
24049
24050 test_257() {
24051         remote_mds_nodsh && skip "remote MDS with nodsh"
24052         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24053                 skip "Need MDS version at least 2.8.55"
24054
24055         test_mkdir $DIR/$tdir
24056
24057         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24058                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24059         stat $DIR/$tdir
24060
24061 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24062         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24063         local facet=mds$((mdtidx + 1))
24064         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24065         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24066
24067         stop $facet || error "stop MDS failed"
24068         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24069                 error "start MDS fail"
24070         wait_recovery_complete $facet
24071 }
24072 run_test 257 "xattr locks are not lost"
24073
24074 # Verify we take the i_mutex when security requires it
24075 test_258a() {
24076 #define OBD_FAIL_IMUTEX_SEC 0x141c
24077         $LCTL set_param fail_loc=0x141c
24078         touch $DIR/$tfile
24079         chmod u+s $DIR/$tfile
24080         chmod a+rwx $DIR/$tfile
24081         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24082         RC=$?
24083         if [ $RC -ne 0 ]; then
24084                 error "error, failed to take i_mutex, rc=$?"
24085         fi
24086         rm -f $DIR/$tfile
24087 }
24088 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24089
24090 # Verify we do NOT take the i_mutex in the normal case
24091 test_258b() {
24092 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24093         $LCTL set_param fail_loc=0x141d
24094         touch $DIR/$tfile
24095         chmod a+rwx $DIR
24096         chmod a+rw $DIR/$tfile
24097         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24098         RC=$?
24099         if [ $RC -ne 0 ]; then
24100                 error "error, took i_mutex unnecessarily, rc=$?"
24101         fi
24102         rm -f $DIR/$tfile
24103
24104 }
24105 run_test 258b "verify i_mutex security behavior"
24106
24107 test_259() {
24108         local file=$DIR/$tfile
24109         local before
24110         local after
24111
24112         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24113
24114         stack_trap "rm -f $file" EXIT
24115
24116         wait_delete_completed
24117         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24118         echo "before: $before"
24119
24120         $LFS setstripe -i 0 -c 1 $file
24121         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24122         sync_all_data
24123         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24124         echo "after write: $after"
24125
24126 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24127         do_facet ost1 $LCTL set_param fail_loc=0x2301
24128         $TRUNCATE $file 0
24129         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24130         echo "after truncate: $after"
24131
24132         stop ost1
24133         do_facet ost1 $LCTL set_param fail_loc=0
24134         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24135         sleep 2
24136         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24137         echo "after restart: $after"
24138         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24139                 error "missing truncate?"
24140
24141         return 0
24142 }
24143 run_test 259 "crash at delayed truncate"
24144
24145 test_260() {
24146 #define OBD_FAIL_MDC_CLOSE               0x806
24147         $LCTL set_param fail_loc=0x80000806
24148         touch $DIR/$tfile
24149
24150 }
24151 run_test 260 "Check mdc_close fail"
24152
24153 ### Data-on-MDT sanity tests ###
24154 test_270a() {
24155         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24156                 skip "Need MDS version at least 2.10.55 for DoM"
24157
24158         # create DoM file
24159         local dom=$DIR/$tdir/dom_file
24160         local tmp=$DIR/$tdir/tmp_file
24161
24162         mkdir_on_mdt0 $DIR/$tdir
24163
24164         # basic checks for DoM component creation
24165         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24166                 error "Can set MDT layout to non-first entry"
24167
24168         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24169                 error "Can define multiple entries as MDT layout"
24170
24171         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24172
24173         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24174         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24175         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24176
24177         local mdtidx=$($LFS getstripe -m $dom)
24178         local mdtname=MDT$(printf %04x $mdtidx)
24179         local facet=mds$((mdtidx + 1))
24180         local space_check=1
24181
24182         # Skip free space checks with ZFS
24183         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24184
24185         # write
24186         sync
24187         local size_tmp=$((65536 * 3))
24188         local mdtfree1=$(do_facet $facet \
24189                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24190
24191         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24192         # check also direct IO along write
24193         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24194         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24195         sync
24196         cmp $tmp $dom || error "file data is different"
24197         [ $(stat -c%s $dom) == $size_tmp ] ||
24198                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24199         if [ $space_check == 1 ]; then
24200                 local mdtfree2=$(do_facet $facet \
24201                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24202
24203                 # increase in usage from by $size_tmp
24204                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24205                         error "MDT free space wrong after write: " \
24206                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24207         fi
24208
24209         # truncate
24210         local size_dom=10000
24211
24212         $TRUNCATE $dom $size_dom
24213         [ $(stat -c%s $dom) == $size_dom ] ||
24214                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24215         if [ $space_check == 1 ]; then
24216                 mdtfree1=$(do_facet $facet \
24217                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24218                 # decrease in usage from $size_tmp to new $size_dom
24219                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24220                   $(((size_tmp - size_dom) / 1024)) ] ||
24221                         error "MDT free space is wrong after truncate: " \
24222                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24223         fi
24224
24225         # append
24226         cat $tmp >> $dom
24227         sync
24228         size_dom=$((size_dom + size_tmp))
24229         [ $(stat -c%s $dom) == $size_dom ] ||
24230                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24231         if [ $space_check == 1 ]; then
24232                 mdtfree2=$(do_facet $facet \
24233                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24234                 # increase in usage by $size_tmp from previous
24235                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24236                         error "MDT free space is wrong after append: " \
24237                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24238         fi
24239
24240         # delete
24241         rm $dom
24242         if [ $space_check == 1 ]; then
24243                 mdtfree1=$(do_facet $facet \
24244                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24245                 # decrease in usage by $size_dom from previous
24246                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24247                         error "MDT free space is wrong after removal: " \
24248                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24249         fi
24250
24251         # combined striping
24252         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24253                 error "Can't create DoM + OST striping"
24254
24255         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24256         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24257         # check also direct IO along write
24258         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24259         sync
24260         cmp $tmp $dom || error "file data is different"
24261         [ $(stat -c%s $dom) == $size_tmp ] ||
24262                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24263         rm $dom $tmp
24264
24265         return 0
24266 }
24267 run_test 270a "DoM: basic functionality tests"
24268
24269 test_270b() {
24270         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24271                 skip "Need MDS version at least 2.10.55"
24272
24273         local dom=$DIR/$tdir/dom_file
24274         local max_size=1048576
24275
24276         mkdir -p $DIR/$tdir
24277         $LFS setstripe -E $max_size -L mdt $dom
24278
24279         # truncate over the limit
24280         $TRUNCATE $dom $(($max_size + 1)) &&
24281                 error "successful truncate over the maximum size"
24282         # write over the limit
24283         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24284                 error "successful write over the maximum size"
24285         # append over the limit
24286         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24287         echo "12345" >> $dom && error "successful append over the maximum size"
24288         rm $dom
24289
24290         return 0
24291 }
24292 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24293
24294 test_270c() {
24295         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24296                 skip "Need MDS version at least 2.10.55"
24297
24298         mkdir -p $DIR/$tdir
24299         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24300
24301         # check files inherit DoM EA
24302         touch $DIR/$tdir/first
24303         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24304                 error "bad pattern"
24305         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24306                 error "bad stripe count"
24307         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24308                 error "bad stripe size"
24309
24310         # check directory inherits DoM EA and uses it as default
24311         mkdir $DIR/$tdir/subdir
24312         touch $DIR/$tdir/subdir/second
24313         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24314                 error "bad pattern in sub-directory"
24315         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24316                 error "bad stripe count in sub-directory"
24317         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24318                 error "bad stripe size in sub-directory"
24319         return 0
24320 }
24321 run_test 270c "DoM: DoM EA inheritance tests"
24322
24323 test_270d() {
24324         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24325                 skip "Need MDS version at least 2.10.55"
24326
24327         mkdir -p $DIR/$tdir
24328         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24329
24330         # inherit default DoM striping
24331         mkdir $DIR/$tdir/subdir
24332         touch $DIR/$tdir/subdir/f1
24333
24334         # change default directory striping
24335         $LFS setstripe -c 1 $DIR/$tdir/subdir
24336         touch $DIR/$tdir/subdir/f2
24337         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24338                 error "wrong default striping in file 2"
24339         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24340                 error "bad pattern in file 2"
24341         return 0
24342 }
24343 run_test 270d "DoM: change striping from DoM to RAID0"
24344
24345 test_270e() {
24346         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24347                 skip "Need MDS version at least 2.10.55"
24348
24349         mkdir -p $DIR/$tdir/dom
24350         mkdir -p $DIR/$tdir/norm
24351         DOMFILES=20
24352         NORMFILES=10
24353         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24354         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24355
24356         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24357         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24358
24359         # find DoM files by layout
24360         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24361         [ $NUM -eq  $DOMFILES ] ||
24362                 error "lfs find -L: found $NUM, expected $DOMFILES"
24363         echo "Test 1: lfs find 20 DOM files by layout: OK"
24364
24365         # there should be 1 dir with default DOM striping
24366         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24367         [ $NUM -eq  1 ] ||
24368                 error "lfs find -L: found $NUM, expected 1 dir"
24369         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24370
24371         # find DoM files by stripe size
24372         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24373         [ $NUM -eq  $DOMFILES ] ||
24374                 error "lfs find -S: found $NUM, expected $DOMFILES"
24375         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24376
24377         # find files by stripe offset except DoM files
24378         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24379         [ $NUM -eq  $NORMFILES ] ||
24380                 error "lfs find -i: found $NUM, expected $NORMFILES"
24381         echo "Test 5: lfs find no DOM files by stripe index: OK"
24382         return 0
24383 }
24384 run_test 270e "DoM: lfs find with DoM files test"
24385
24386 test_270f() {
24387         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24388                 skip "Need MDS version at least 2.10.55"
24389
24390         local mdtname=${FSNAME}-MDT0000-mdtlov
24391         local dom=$DIR/$tdir/dom_file
24392         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24393                                                 lod.$mdtname.dom_stripesize)
24394         local dom_limit=131072
24395
24396         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24397         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24398                                                 lod.$mdtname.dom_stripesize)
24399         [ ${dom_limit} -eq ${dom_current} ] ||
24400                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24401
24402         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24403         $LFS setstripe -d $DIR/$tdir
24404         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24405                 error "Can't set directory default striping"
24406
24407         # exceed maximum stripe size
24408         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24409                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24410         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24411                 error "Able to create DoM component size more than LOD limit"
24412
24413         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24414         dom_current=$(do_facet mds1 $LCTL get_param -n \
24415                                                 lod.$mdtname.dom_stripesize)
24416         [ 0 -eq ${dom_current} ] ||
24417                 error "Can't set zero DoM stripe limit"
24418         rm $dom
24419
24420         # attempt to create DoM file on server with disabled DoM should
24421         # remove DoM entry from layout and be succeed
24422         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24423                 error "Can't create DoM file (DoM is disabled)"
24424         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24425                 error "File has DoM component while DoM is disabled"
24426         rm $dom
24427
24428         # attempt to create DoM file with only DoM stripe should return error
24429         $LFS setstripe -E $dom_limit -L mdt $dom &&
24430                 error "Able to create DoM-only file while DoM is disabled"
24431
24432         # too low values to be aligned with smallest stripe size 64K
24433         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24434         dom_current=$(do_facet mds1 $LCTL get_param -n \
24435                                                 lod.$mdtname.dom_stripesize)
24436         [ 30000 -eq ${dom_current} ] &&
24437                 error "Can set too small DoM stripe limit"
24438
24439         # 64K is a minimal stripe size in Lustre, expect limit of that size
24440         [ 65536 -eq ${dom_current} ] ||
24441                 error "Limit is not set to 64K but ${dom_current}"
24442
24443         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24444         dom_current=$(do_facet mds1 $LCTL get_param -n \
24445                                                 lod.$mdtname.dom_stripesize)
24446         echo $dom_current
24447         [ 2147483648 -eq ${dom_current} ] &&
24448                 error "Can set too large DoM stripe limit"
24449
24450         do_facet mds1 $LCTL set_param -n \
24451                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24452         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24453                 error "Can't create DoM component size after limit change"
24454         do_facet mds1 $LCTL set_param -n \
24455                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24456         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24457                 error "Can't create DoM file after limit decrease"
24458         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24459                 error "Can create big DoM component after limit decrease"
24460         touch ${dom}_def ||
24461                 error "Can't create file with old default layout"
24462
24463         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24464         return 0
24465 }
24466 run_test 270f "DoM: maximum DoM stripe size checks"
24467
24468 test_270g() {
24469         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24470                 skip "Need MDS version at least 2.13.52"
24471         local dom=$DIR/$tdir/$tfile
24472
24473         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24474         local lodname=${FSNAME}-MDT0000-mdtlov
24475
24476         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24477         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24478         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24479         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24480
24481         local dom_limit=1024
24482         local dom_threshold="50%"
24483
24484         $LFS setstripe -d $DIR/$tdir
24485         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24486                 error "Can't set directory default striping"
24487
24488         do_facet mds1 $LCTL set_param -n \
24489                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24490         # set 0 threshold and create DOM file to change tunable stripesize
24491         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24492         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24493                 error "Failed to create $dom file"
24494         # now tunable dom_cur_stripesize should reach maximum
24495         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24496                                         lod.${lodname}.dom_stripesize_cur_kb)
24497         [[ $dom_current == $dom_limit ]] ||
24498                 error "Current DOM stripesize is not maximum"
24499         rm $dom
24500
24501         # set threshold for further tests
24502         do_facet mds1 $LCTL set_param -n \
24503                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24504         echo "DOM threshold is $dom_threshold free space"
24505         local dom_def
24506         local dom_set
24507         # Spoof bfree to exceed threshold
24508         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24509         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24510         for spfree in 40 20 0 15 30 55; do
24511                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24512                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24513                         error "Failed to create $dom file"
24514                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24515                                         lod.${lodname}.dom_stripesize_cur_kb)
24516                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24517                 [[ $dom_def != $dom_current ]] ||
24518                         error "Default stripe size was not changed"
24519                 if (( spfree > 0 )) ; then
24520                         dom_set=$($LFS getstripe -S $dom)
24521                         (( dom_set == dom_def * 1024 )) ||
24522                                 error "DOM component size is still old"
24523                 else
24524                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24525                                 error "DoM component is set with no free space"
24526                 fi
24527                 rm $dom
24528                 dom_current=$dom_def
24529         done
24530 }
24531 run_test 270g "DoM: default DoM stripe size depends on free space"
24532
24533 test_270h() {
24534         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24535                 skip "Need MDS version at least 2.13.53"
24536
24537         local mdtname=${FSNAME}-MDT0000-mdtlov
24538         local dom=$DIR/$tdir/$tfile
24539         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24540
24541         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24542         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24543
24544         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24545         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24546                 error "can't create OST file"
24547         # mirrored file with DOM entry in the second mirror
24548         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24549                 error "can't create mirror with DoM component"
24550
24551         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24552
24553         # DOM component in the middle and has other enries in the same mirror,
24554         # should succeed but lost DoM component
24555         $LFS setstripe --copy=${dom}_1 $dom ||
24556                 error "Can't create file from OST|DOM mirror layout"
24557         # check new file has no DoM layout after all
24558         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24559                 error "File has DoM component while DoM is disabled"
24560 }
24561 run_test 270h "DoM: DoM stripe removal when disabled on server"
24562
24563 test_270i() {
24564         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24565                 skip "Need MDS version at least 2.14.54"
24566
24567         mkdir $DIR/$tdir
24568         # DoM with plain layout
24569         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24570                 error "default plain layout with DoM must fail"
24571         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24572                 error "setstripe plain file layout with DoM must fail"
24573         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24574                 error "default DoM layout with bad striping must fail"
24575         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24576                 error "setstripe to DoM layout with bad striping must fail"
24577         return 0
24578 }
24579 run_test 270i "DoM: setting invalid DoM striping should fail"
24580
24581 test_270j() {
24582         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24583                 skip "Need MDS version at least 2.15.55.203"
24584
24585         local dom=$DIR/$tdir/$tfile
24586         local odv
24587         local ndv
24588
24589         mkdir -p $DIR/$tdir
24590
24591         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24592
24593         odv=$($LFS data_version $dom)
24594         chmod 666 $dom
24595         mv $dom ${dom}_moved
24596         link ${dom}_moved $dom
24597         setfattr -n user.attrx -v "some_attr" $dom
24598         ndv=$($LFS data_version $dom)
24599         (( $ndv == $odv )) ||
24600                 error "data version was changed by metadata operations"
24601
24602         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24603                 error "failed to write data into $dom"
24604         cancel_lru_locks mdc
24605         ndv=$($LFS data_version $dom)
24606         (( $ndv != $odv )) ||
24607                 error "data version wasn't changed on write"
24608
24609         odv=$ndv
24610         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24611         ndv=$($LFS data_version $dom)
24612         (( $ndv != $odv )) ||
24613                 error "data version wasn't changed on truncate down"
24614
24615         odv=$ndv
24616         $TRUNCATE $dom 25000
24617         ndv=$($LFS data_version $dom)
24618         (( $ndv != $odv )) ||
24619                 error "data version wasn't changed on truncate up"
24620
24621         # check also fallocate for ldiskfs
24622         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24623                 odv=$ndv
24624                 fallocate -l 1048576 $dom
24625                 ndv=$($LFS data_version $dom)
24626                 (( $ndv != $odv )) ||
24627                         error "data version wasn't changed on fallocate"
24628
24629                 odv=$ndv
24630                 fallocate -p --offset 4096 -l 4096 $dom
24631                 ndv=$($LFS data_version $dom)
24632                 (( $ndv != $odv )) ||
24633                         error "data version wasn't changed on fallocate punch"
24634         fi
24635 }
24636 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24637
24638 test_271a() {
24639         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24640                 skip "Need MDS version at least 2.10.55"
24641
24642         local dom=$DIR/$tdir/dom
24643
24644         mkdir -p $DIR/$tdir
24645
24646         $LFS setstripe -E 1024K -L mdt $dom
24647
24648         lctl set_param -n mdc.*.stats=clear
24649         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24650         cat $dom > /dev/null
24651         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24652         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24653         ls $dom
24654         rm -f $dom
24655 }
24656 run_test 271a "DoM: data is cached for read after write"
24657
24658 test_271b() {
24659         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24660                 skip "Need MDS version at least 2.10.55"
24661
24662         local dom=$DIR/$tdir/dom
24663
24664         mkdir -p $DIR/$tdir
24665
24666         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24667
24668         lctl set_param -n mdc.*.stats=clear
24669         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24670         cancel_lru_locks mdc
24671         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24672         # second stat to check size is cached on client
24673         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24674         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24675         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24676         rm -f $dom
24677 }
24678 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24679
24680 test_271ba() {
24681         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24682                 skip "Need MDS version at least 2.10.55"
24683
24684         local dom=$DIR/$tdir/dom
24685
24686         mkdir -p $DIR/$tdir
24687
24688         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24689
24690         lctl set_param -n mdc.*.stats=clear
24691         lctl set_param -n osc.*.stats=clear
24692         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24693         cancel_lru_locks mdc
24694         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24695         # second stat to check size is cached on client
24696         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24697         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24698         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24699         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24700         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24701         rm -f $dom
24702 }
24703 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24704
24705
24706 get_mdc_stats() {
24707         local mdtidx=$1
24708         local param=$2
24709         local mdt=MDT$(printf %04x $mdtidx)
24710
24711         if [ -z $param ]; then
24712                 lctl get_param -n mdc.*$mdt*.stats
24713         else
24714                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24715         fi
24716 }
24717
24718 test_271c() {
24719         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24720                 skip "Need MDS version at least 2.10.55"
24721
24722         local dom=$DIR/$tdir/dom
24723
24724         mkdir -p $DIR/$tdir
24725
24726         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24727
24728         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24729         local facet=mds$((mdtidx + 1))
24730
24731         cancel_lru_locks mdc
24732         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24733         createmany -o $dom 1000
24734         lctl set_param -n mdc.*.stats=clear
24735         smalliomany -w $dom 1000 200
24736         get_mdc_stats $mdtidx
24737         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24738         # Each file has 1 open, 1 IO enqueues, total 2000
24739         # but now we have also +1 getxattr for security.capability, total 3000
24740         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24741         unlinkmany $dom 1000
24742
24743         cancel_lru_locks mdc
24744         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24745         createmany -o $dom 1000
24746         lctl set_param -n mdc.*.stats=clear
24747         smalliomany -w $dom 1000 200
24748         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24749         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24750         # for OPEN and IO lock.
24751         [ $((enq - enq_2)) -ge 1000 ] ||
24752                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24753         unlinkmany $dom 1000
24754         return 0
24755 }
24756 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24757
24758 cleanup_271def_tests() {
24759         trap 0
24760         rm -f $1
24761 }
24762
24763 test_271d() {
24764         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24765                 skip "Need MDS version at least 2.10.57"
24766
24767         local dom=$DIR/$tdir/dom
24768         local tmp=$TMP/$tfile
24769         trap "cleanup_271def_tests $tmp" EXIT
24770
24771         mkdir -p $DIR/$tdir
24772
24773         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24774
24775         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24776
24777         cancel_lru_locks mdc
24778         dd if=/dev/urandom of=$tmp bs=1000 count=1
24779         dd if=$tmp of=$dom bs=1000 count=1
24780         cancel_lru_locks mdc
24781
24782         cat /etc/hosts >> $tmp
24783         lctl set_param -n mdc.*.stats=clear
24784
24785         # append data to the same file it should update local page
24786         echo "Append to the same page"
24787         cat /etc/hosts >> $dom
24788         local num=$(get_mdc_stats $mdtidx ost_read)
24789         local ra=$(get_mdc_stats $mdtidx req_active)
24790         local rw=$(get_mdc_stats $mdtidx req_waittime)
24791
24792         [ -z $num ] || error "$num READ RPC occured"
24793         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24794         echo "... DONE"
24795
24796         # compare content
24797         cmp $tmp $dom || error "file miscompare"
24798
24799         cancel_lru_locks mdc
24800         lctl set_param -n mdc.*.stats=clear
24801
24802         echo "Open and read file"
24803         cat $dom > /dev/null
24804         local num=$(get_mdc_stats $mdtidx ost_read)
24805         local ra=$(get_mdc_stats $mdtidx req_active)
24806         local rw=$(get_mdc_stats $mdtidx req_waittime)
24807
24808         [ -z $num ] || error "$num READ RPC occured"
24809         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24810         echo "... DONE"
24811
24812         # compare content
24813         cmp $tmp $dom || error "file miscompare"
24814
24815         return 0
24816 }
24817 run_test 271d "DoM: read on open (1K file in reply buffer)"
24818
24819 test_271f() {
24820         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24821                 skip "Need MDS version at least 2.10.57"
24822
24823         local dom=$DIR/$tdir/dom
24824         local tmp=$TMP/$tfile
24825         trap "cleanup_271def_tests $tmp" EXIT
24826
24827         mkdir -p $DIR/$tdir
24828
24829         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24830
24831         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24832
24833         cancel_lru_locks mdc
24834         dd if=/dev/urandom of=$tmp bs=265000 count=1
24835         dd if=$tmp of=$dom bs=265000 count=1
24836         cancel_lru_locks mdc
24837         cat /etc/hosts >> $tmp
24838         lctl set_param -n mdc.*.stats=clear
24839
24840         echo "Append to the same page"
24841         cat /etc/hosts >> $dom
24842         local num=$(get_mdc_stats $mdtidx ost_read)
24843         local ra=$(get_mdc_stats $mdtidx req_active)
24844         local rw=$(get_mdc_stats $mdtidx req_waittime)
24845
24846         [ -z $num ] || error "$num READ RPC occured"
24847         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24848         echo "... DONE"
24849
24850         # compare content
24851         cmp $tmp $dom || error "file miscompare"
24852
24853         cancel_lru_locks mdc
24854         lctl set_param -n mdc.*.stats=clear
24855
24856         echo "Open and read file"
24857         cat $dom > /dev/null
24858         local num=$(get_mdc_stats $mdtidx ost_read)
24859         local ra=$(get_mdc_stats $mdtidx req_active)
24860         local rw=$(get_mdc_stats $mdtidx req_waittime)
24861
24862         [ -z $num ] && num=0
24863         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24864         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24865         echo "... DONE"
24866
24867         # compare content
24868         cmp $tmp $dom || error "file miscompare"
24869
24870         return 0
24871 }
24872 run_test 271f "DoM: read on open (200K file and read tail)"
24873
24874 test_271g() {
24875         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24876                 skip "Skipping due to old client or server version"
24877
24878         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24879         # to get layout
24880         $CHECKSTAT -t file $DIR1/$tfile
24881
24882         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24883         MULTIOP_PID=$!
24884         sleep 1
24885         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24886         $LCTL set_param fail_loc=0x80000314
24887         rm $DIR1/$tfile || error "Unlink fails"
24888         RC=$?
24889         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24890         [ $RC -eq 0 ] || error "Failed write to stale object"
24891 }
24892 run_test 271g "Discard DoM data vs client flush race"
24893
24894 test_272a() {
24895         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24896                 skip "Need MDS version at least 2.11.50"
24897
24898         local dom=$DIR/$tdir/dom
24899         mkdir -p $DIR/$tdir
24900
24901         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24902         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24903                 error "failed to write data into $dom"
24904         local old_md5=$(md5sum $dom)
24905
24906         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24907                 error "failed to migrate to the same DoM component"
24908
24909         local new_md5=$(md5sum $dom)
24910
24911         [ "$old_md5" == "$new_md5" ] ||
24912                 error "md5sum differ: $old_md5, $new_md5"
24913
24914         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24915                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24916 }
24917 run_test 272a "DoM migration: new layout with the same DOM component"
24918
24919 test_272b() {
24920         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24921                 skip "Need MDS version at least 2.11.50"
24922
24923         local dom=$DIR/$tdir/dom
24924         mkdir -p $DIR/$tdir
24925         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24926         stack_trap "rm -rf $DIR/$tdir"
24927
24928         local mdtidx=$($LFS getstripe -m $dom)
24929         local mdtname=MDT$(printf %04x $mdtidx)
24930         local facet=mds$((mdtidx + 1))
24931
24932         local mdtfree1=$(do_facet $facet \
24933                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24934         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24935                 error "failed to write data into $dom"
24936         local old_md5=$(md5sum $dom)
24937         cancel_lru_locks mdc
24938         local mdtfree1=$(do_facet $facet \
24939                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24940
24941         $LFS migrate -c2 $dom ||
24942                 error "failed to migrate to the new composite layout"
24943         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24944                 error "MDT stripe was not removed"
24945         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24946                 error "$dir1 shouldn't have DATAVER EA"
24947
24948         cancel_lru_locks mdc
24949         local new_md5=$(md5sum $dom)
24950         [ "$old_md5" == "$new_md5" ] ||
24951                 error "$old_md5 != $new_md5"
24952
24953         # Skip free space checks with ZFS
24954         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24955                 local mdtfree2=$(do_facet $facet \
24956                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24957                 [ $mdtfree2 -gt $mdtfree1 ] ||
24958                         error "MDT space is not freed after migration"
24959         fi
24960         return 0
24961 }
24962 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24963
24964 test_272c() {
24965         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24966                 skip "Need MDS version at least 2.11.50"
24967
24968         local dom=$DIR/$tdir/$tfile
24969         mkdir -p $DIR/$tdir
24970         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24971         stack_trap "rm -rf $DIR/$tdir"
24972
24973         local mdtidx=$($LFS getstripe -m $dom)
24974         local mdtname=MDT$(printf %04x $mdtidx)
24975         local facet=mds$((mdtidx + 1))
24976
24977         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24978                 error "failed to write data into $dom"
24979         local old_md5=$(md5sum $dom)
24980         cancel_lru_locks mdc
24981         local mdtfree1=$(do_facet $facet \
24982                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24983
24984         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24985                 error "failed to migrate to the new composite layout"
24986         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24987                 error "MDT stripe was not removed"
24988
24989         cancel_lru_locks mdc
24990         local new_md5=$(md5sum $dom)
24991         [ "$old_md5" == "$new_md5" ] ||
24992                 error "$old_md5 != $new_md5"
24993
24994         # Skip free space checks with ZFS
24995         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24996                 local mdtfree2=$(do_facet $facet \
24997                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24998                 [ $mdtfree2 -gt $mdtfree1 ] ||
24999                         error "MDS space is not freed after migration"
25000         fi
25001         return 0
25002 }
25003 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25004
25005 test_272d() {
25006         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25007                 skip "Need MDS version at least 2.12.55"
25008
25009         local dom=$DIR/$tdir/$tfile
25010         mkdir -p $DIR/$tdir
25011         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25012
25013         local mdtidx=$($LFS getstripe -m $dom)
25014         local mdtname=MDT$(printf %04x $mdtidx)
25015         local facet=mds$((mdtidx + 1))
25016
25017         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25018                 error "failed to write data into $dom"
25019         local old_md5=$(md5sum $dom)
25020         cancel_lru_locks mdc
25021         local mdtfree1=$(do_facet $facet \
25022                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25023
25024         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25025                 error "failed mirroring to the new composite layout"
25026         $LFS mirror resync $dom ||
25027                 error "failed mirror resync"
25028         $LFS mirror split --mirror-id 1 -d $dom ||
25029                 error "failed mirror split"
25030
25031         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25032                 error "MDT stripe was not removed"
25033
25034         cancel_lru_locks mdc
25035         local new_md5=$(md5sum $dom)
25036         [ "$old_md5" == "$new_md5" ] ||
25037                 error "$old_md5 != $new_md5"
25038
25039         # Skip free space checks with ZFS
25040         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25041                 local mdtfree2=$(do_facet $facet \
25042                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25043                 [ $mdtfree2 -gt $mdtfree1 ] ||
25044                         error "MDS space is not freed after DOM mirror deletion"
25045         fi
25046         return 0
25047 }
25048 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25049
25050 test_272e() {
25051         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25052                 skip "Need MDS version at least 2.12.55"
25053
25054         local dom=$DIR/$tdir/$tfile
25055         mkdir -p $DIR/$tdir
25056         $LFS setstripe -c 2 $dom
25057
25058         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25059                 error "failed to write data into $dom"
25060         local old_md5=$(md5sum $dom)
25061         cancel_lru_locks
25062
25063         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25064                 error "failed mirroring to the DOM layout"
25065         $LFS mirror resync $dom ||
25066                 error "failed mirror resync"
25067         $LFS mirror split --mirror-id 1 -d $dom ||
25068                 error "failed mirror split"
25069
25070         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25071                 error "MDT stripe wasn't set"
25072
25073         cancel_lru_locks
25074         local new_md5=$(md5sum $dom)
25075         [ "$old_md5" == "$new_md5" ] ||
25076                 error "$old_md5 != $new_md5"
25077
25078         return 0
25079 }
25080 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25081
25082 test_272f() {
25083         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25084                 skip "Need MDS version at least 2.12.55"
25085
25086         local dom=$DIR/$tdir/$tfile
25087         mkdir -p $DIR/$tdir
25088         $LFS setstripe -c 2 $dom
25089
25090         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25091                 error "failed to write data into $dom"
25092         local old_md5=$(md5sum $dom)
25093         cancel_lru_locks
25094
25095         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25096                 error "failed migrating to the DOM file"
25097
25098         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25099                 error "MDT stripe wasn't set"
25100
25101         cancel_lru_locks
25102         local new_md5=$(md5sum $dom)
25103         [ "$old_md5" != "$new_md5" ] &&
25104                 error "$old_md5 != $new_md5"
25105
25106         return 0
25107 }
25108 run_test 272f "DoM migration: OST-striped file to DOM file"
25109
25110 test_273a() {
25111         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25112                 skip "Need MDS version at least 2.11.50"
25113
25114         # Layout swap cannot be done if either file has DOM component,
25115         # this will never be supported, migration should be used instead
25116
25117         local dom=$DIR/$tdir/$tfile
25118         mkdir -p $DIR/$tdir
25119
25120         $LFS setstripe -c2 ${dom}_plain
25121         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25122         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25123                 error "can swap layout with DoM component"
25124         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25125                 error "can swap layout with DoM component"
25126
25127         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25128         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25129                 error "can swap layout with DoM component"
25130         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25131                 error "can swap layout with DoM component"
25132         return 0
25133 }
25134 run_test 273a "DoM: layout swapping should fail with DOM"
25135
25136 test_273b() {
25137         mkdir -p $DIR/$tdir
25138         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25139
25140 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25141         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25142
25143         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25144 }
25145 run_test 273b "DoM: race writeback and object destroy"
25146
25147 test_273c() {
25148         mkdir -p $DIR/$tdir
25149         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25150
25151         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25152         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25153
25154         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25155 }
25156 run_test 273c "race writeback and object destroy"
25157
25158 test_275() {
25159         remote_ost_nodsh && skip "remote OST with nodsh"
25160         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25161                 skip "Need OST version >= 2.10.57"
25162
25163         local file=$DIR/$tfile
25164         local oss
25165
25166         oss=$(comma_list $(osts_nodes))
25167
25168         dd if=/dev/urandom of=$file bs=1M count=2 ||
25169                 error "failed to create a file"
25170         stack_trap "rm -f $file"
25171         cancel_lru_locks osc
25172
25173         #lock 1
25174         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25175                 error "failed to read a file"
25176
25177 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25178         $LCTL set_param fail_loc=0x8000031f
25179
25180         cancel_lru_locks osc &
25181         sleep 1
25182
25183 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25184         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25185         #IO takes another lock, but matches the PENDING one
25186         #and places it to the IO RPC
25187         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25188                 error "failed to read a file with PENDING lock"
25189 }
25190 run_test 275 "Read on a canceled duplicate lock"
25191
25192 test_276() {
25193         remote_ost_nodsh && skip "remote OST with nodsh"
25194         local pid
25195
25196         do_facet ost1 "(while true; do \
25197                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25198                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25199         pid=$!
25200
25201         for LOOP in $(seq 20); do
25202                 stop ost1
25203                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25204         done
25205         kill -9 $pid
25206         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25207                 rm $TMP/sanity_276_pid"
25208 }
25209 run_test 276 "Race between mount and obd_statfs"
25210
25211 test_277() {
25212         $LCTL set_param ldlm.namespaces.*.lru_size=0
25213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25214         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25215                           awk '/^used_mb/ { print $2 }')
25216         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25218                 oflag=direct conv=notrunc
25219         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25220                     awk '/^used_mb/ { print $2 }')
25221         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25222 }
25223 run_test 277 "Direct IO shall drop page cache"
25224
25225 test_278() {
25226         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25227         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25228         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25229                 skip "needs the same host for mdt1 mdt2" && return
25230
25231         local pid1
25232         local pid2
25233
25234 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25235         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25236         stop mds2 &
25237         pid2=$!
25238
25239         stop mds1
25240
25241         echo "Starting MDTs"
25242         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25243         wait $pid2
25244 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25245 #will return NULL
25246         do_facet mds2 $LCTL set_param fail_loc=0
25247
25248         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25249         wait_recovery_complete mds2
25250 }
25251 run_test 278 "Race starting MDS between MDTs stop/start"
25252
25253 test_280() {
25254         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25255                 skip "Need MGS version at least 2.13.52"
25256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25257         combined_mgs_mds || skip "needs combined MGS/MDT"
25258
25259         umount_client $MOUNT
25260 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25261         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25262
25263         mount_client $MOUNT &
25264         sleep 1
25265         stop mgs || error "stop mgs failed"
25266         #for a race mgs would crash
25267         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25268         # make sure we unmount client before remounting
25269         wait
25270         umount_client $MOUNT
25271         mount_client $MOUNT || error "mount client failed"
25272 }
25273 run_test 280 "Race between MGS umount and client llog processing"
25274
25275 cleanup_test_300() {
25276         trap 0
25277         umask $SAVE_UMASK
25278 }
25279 test_striped_dir() {
25280         local mdt_index=$1
25281         local stripe_count
25282         local stripe_index
25283
25284         mkdir -p $DIR/$tdir
25285
25286         SAVE_UMASK=$(umask)
25287         trap cleanup_test_300 RETURN EXIT
25288
25289         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25290                                                 $DIR/$tdir/striped_dir ||
25291                 error "set striped dir error"
25292
25293         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25294         [ "$mode" = "755" ] || error "expect 755 got $mode"
25295
25296         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25297                 error "getdirstripe failed"
25298         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25299         if [ "$stripe_count" != "2" ]; then
25300                 error "1:stripe_count is $stripe_count, expect 2"
25301         fi
25302         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25303         if [ "$stripe_count" != "2" ]; then
25304                 error "2:stripe_count is $stripe_count, expect 2"
25305         fi
25306
25307         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25308         if [ "$stripe_index" != "$mdt_index" ]; then
25309                 error "stripe_index is $stripe_index, expect $mdt_index"
25310         fi
25311
25312         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25313                 error "nlink error after create striped dir"
25314
25315         mkdir $DIR/$tdir/striped_dir/a
25316         mkdir $DIR/$tdir/striped_dir/b
25317
25318         stat $DIR/$tdir/striped_dir/a ||
25319                 error "create dir under striped dir failed"
25320         stat $DIR/$tdir/striped_dir/b ||
25321                 error "create dir under striped dir failed"
25322
25323         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25324                 error "nlink error after mkdir"
25325
25326         rmdir $DIR/$tdir/striped_dir/a
25327         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25328                 error "nlink error after rmdir"
25329
25330         rmdir $DIR/$tdir/striped_dir/b
25331         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25332                 error "nlink error after rmdir"
25333
25334         chattr +i $DIR/$tdir/striped_dir
25335         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25336                 error "immutable flags not working under striped dir!"
25337         chattr -i $DIR/$tdir/striped_dir
25338
25339         rmdir $DIR/$tdir/striped_dir ||
25340                 error "rmdir striped dir error"
25341
25342         cleanup_test_300
25343
25344         true
25345 }
25346
25347 test_300a() {
25348         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25349                 skip "skipped for lustre < 2.7.0"
25350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25352
25353         test_striped_dir 0 || error "failed on striped dir on MDT0"
25354         test_striped_dir 1 || error "failed on striped dir on MDT0"
25355 }
25356 run_test 300a "basic striped dir sanity test"
25357
25358 test_300b() {
25359         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25360                 skip "skipped for lustre < 2.7.0"
25361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25363
25364         local i
25365         local mtime1
25366         local mtime2
25367         local mtime3
25368
25369         test_mkdir $DIR/$tdir || error "mkdir fail"
25370         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25371                 error "set striped dir error"
25372         for i in {0..9}; do
25373                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25374                 sleep 1
25375                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25376                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25377                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25378                 sleep 1
25379                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25380                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25381                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25382         done
25383         true
25384 }
25385 run_test 300b "check ctime/mtime for striped dir"
25386
25387 test_300c() {
25388         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25389                 skip "skipped for lustre < 2.7.0"
25390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25392
25393         local file_count
25394
25395         mkdir_on_mdt0 $DIR/$tdir
25396         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25397                 error "set striped dir error"
25398
25399         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25400                 error "chown striped dir failed"
25401
25402         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25403                 error "create 5k files failed"
25404
25405         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25406
25407         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25408
25409         rm -rf $DIR/$tdir
25410 }
25411 run_test 300c "chown && check ls under striped directory"
25412
25413 test_300d() {
25414         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25415                 skip "skipped for lustre < 2.7.0"
25416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25418
25419         local stripe_count
25420         local file
25421
25422         mkdir -p $DIR/$tdir
25423         $LFS setstripe -c 2 $DIR/$tdir
25424
25425         #local striped directory
25426         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25427                 error "set striped dir error"
25428         #look at the directories for debug purposes
25429         ls -l $DIR/$tdir
25430         $LFS getdirstripe $DIR/$tdir
25431         ls -l $DIR/$tdir/striped_dir
25432         $LFS getdirstripe $DIR/$tdir/striped_dir
25433         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25434                 error "create 10 files failed"
25435
25436         #remote striped directory
25437         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25438                 error "set striped dir error"
25439         #look at the directories for debug purposes
25440         ls -l $DIR/$tdir
25441         $LFS getdirstripe $DIR/$tdir
25442         ls -l $DIR/$tdir/remote_striped_dir
25443         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25444         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25445                 error "create 10 files failed"
25446
25447         for file in $(find $DIR/$tdir); do
25448                 stripe_count=$($LFS getstripe -c $file)
25449                 [ $stripe_count -eq 2 ] ||
25450                         error "wrong stripe $stripe_count for $file"
25451         done
25452
25453         rm -rf $DIR/$tdir
25454 }
25455 run_test 300d "check default stripe under striped directory"
25456
25457 test_300e() {
25458         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25459                 skip "Need MDS version at least 2.7.55"
25460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25462
25463         local stripe_count
25464         local file
25465
25466         mkdir -p $DIR/$tdir
25467
25468         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25469                 error "set striped dir error"
25470
25471         touch $DIR/$tdir/striped_dir/a
25472         touch $DIR/$tdir/striped_dir/b
25473         touch $DIR/$tdir/striped_dir/c
25474
25475         mkdir $DIR/$tdir/striped_dir/dir_a
25476         mkdir $DIR/$tdir/striped_dir/dir_b
25477         mkdir $DIR/$tdir/striped_dir/dir_c
25478
25479         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25480                 error "set striped adir under striped dir error"
25481
25482         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25483                 error "set striped bdir under striped dir error"
25484
25485         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25486                 error "set striped cdir under striped dir error"
25487
25488         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25489                 error "rename dir under striped dir fails"
25490
25491         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25492                 error "rename dir under different stripes fails"
25493
25494         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25495                 error "rename file under striped dir should succeed"
25496
25497         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25498                 error "rename dir under striped dir should succeed"
25499
25500         rm -rf $DIR/$tdir
25501 }
25502 run_test 300e "check rename under striped directory"
25503
25504 test_300f() {
25505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25507         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25508                 skip "Need MDS version at least 2.7.55"
25509
25510         local stripe_count
25511         local file
25512
25513         rm -rf $DIR/$tdir
25514         mkdir -p $DIR/$tdir
25515
25516         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25517                 error "set striped dir error"
25518
25519         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25520                 error "set striped dir error"
25521
25522         touch $DIR/$tdir/striped_dir/a
25523         mkdir $DIR/$tdir/striped_dir/dir_a
25524         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25525                 error "create striped dir under striped dir fails"
25526
25527         touch $DIR/$tdir/striped_dir1/b
25528         mkdir $DIR/$tdir/striped_dir1/dir_b
25529         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25530                 error "create striped dir under striped dir fails"
25531
25532         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25533                 error "rename dir under different striped dir should fail"
25534
25535         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25536                 error "rename striped dir under diff striped dir should fail"
25537
25538         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25539                 error "rename file under diff striped dirs fails"
25540
25541         rm -rf $DIR/$tdir
25542 }
25543 run_test 300f "check rename cross striped directory"
25544
25545 test_300_check_default_striped_dir()
25546 {
25547         local dirname=$1
25548         local default_count=$2
25549         local default_index=$3
25550         local stripe_count
25551         local stripe_index
25552         local dir_stripe_index
25553         local dir
25554
25555         echo "checking $dirname $default_count $default_index"
25556         $LFS setdirstripe -D -c $default_count -i $default_index \
25557                                 -H all_char $DIR/$tdir/$dirname ||
25558                 error "set default stripe on striped dir error"
25559         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25560         [ $stripe_count -eq $default_count ] ||
25561                 error "expect $default_count get $stripe_count for $dirname"
25562
25563         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25564         [ $stripe_index -eq $default_index ] ||
25565                 error "expect $default_index get $stripe_index for $dirname"
25566
25567         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25568                                                 error "create dirs failed"
25569
25570         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25571         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25572         for dir in $(find $DIR/$tdir/$dirname/*); do
25573                 stripe_count=$($LFS getdirstripe -c $dir)
25574                 (( $stripe_count == $default_count )) ||
25575                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25576                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25577                 error "stripe count $default_count != $stripe_count for $dir"
25578
25579                 stripe_index=$($LFS getdirstripe -i $dir)
25580                 [ $default_index -eq -1 ] ||
25581                         [ $stripe_index -eq $default_index ] ||
25582                         error "$stripe_index != $default_index for $dir"
25583
25584                 #check default stripe
25585                 stripe_count=$($LFS getdirstripe -D -c $dir)
25586                 [ $stripe_count -eq $default_count ] ||
25587                 error "default count $default_count != $stripe_count for $dir"
25588
25589                 stripe_index=$($LFS getdirstripe -D -i $dir)
25590                 [ $stripe_index -eq $default_index ] ||
25591                 error "default index $default_index != $stripe_index for $dir"
25592         done
25593         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25594 }
25595
25596 test_300g() {
25597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25598         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25599                 skip "Need MDS version at least 2.7.55"
25600
25601         local dir
25602         local stripe_count
25603         local stripe_index
25604
25605         mkdir_on_mdt0 $DIR/$tdir
25606         mkdir $DIR/$tdir/normal_dir
25607
25608         #Checking when client cache stripe index
25609         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25610         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25611                 error "create striped_dir failed"
25612
25613         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25614                 error "create dir0 fails"
25615         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25616         [ $stripe_index -eq 0 ] ||
25617                 error "dir0 expect index 0 got $stripe_index"
25618
25619         mkdir $DIR/$tdir/striped_dir/dir1 ||
25620                 error "create dir1 fails"
25621         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25622         [ $stripe_index -eq 1 ] ||
25623                 error "dir1 expect index 1 got $stripe_index"
25624
25625         #check default stripe count/stripe index
25626         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25627         test_300_check_default_striped_dir normal_dir 1 0
25628         test_300_check_default_striped_dir normal_dir -1 1
25629         test_300_check_default_striped_dir normal_dir 2 -1
25630
25631         #delete default stripe information
25632         echo "delete default stripeEA"
25633         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25634                 error "set default stripe on striped dir error"
25635
25636         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25637         for dir in $(find $DIR/$tdir/normal_dir/*); do
25638                 stripe_count=$($LFS getdirstripe -c $dir)
25639                 [ $stripe_count -eq 0 ] ||
25640                         error "expect 1 get $stripe_count for $dir"
25641         done
25642 }
25643 run_test 300g "check default striped directory for normal directory"
25644
25645 test_300h() {
25646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25647         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25648                 skip "Need MDS version at least 2.7.55"
25649
25650         local dir
25651         local stripe_count
25652
25653         mkdir $DIR/$tdir
25654         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25655                 error "set striped dir error"
25656
25657         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25658         test_300_check_default_striped_dir striped_dir 1 0
25659         test_300_check_default_striped_dir striped_dir -1 1
25660         test_300_check_default_striped_dir striped_dir 2 -1
25661
25662         #delete default stripe information
25663         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25664                 error "set default stripe on striped dir error"
25665
25666         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25667         for dir in $(find $DIR/$tdir/striped_dir/*); do
25668                 stripe_count=$($LFS getdirstripe -c $dir)
25669                 [ $stripe_count -eq 0 ] ||
25670                         error "expect 1 get $stripe_count for $dir"
25671         done
25672 }
25673 run_test 300h "check default striped directory for striped directory"
25674
25675 test_300i() {
25676         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25677         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25678         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25679                 skip "Need MDS version at least 2.7.55"
25680
25681         local stripe_count
25682         local file
25683
25684         mkdir $DIR/$tdir
25685
25686         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25687                 error "set striped dir error"
25688
25689         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25690                 error "create files under striped dir failed"
25691
25692         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25693                 error "set striped hashdir error"
25694
25695         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25696                 error "create dir0 under hash dir failed"
25697         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25698                 error "create dir1 under hash dir failed"
25699         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25700                 error "create dir2 under hash dir failed"
25701
25702         # unfortunately, we need to umount to clear dir layout cache for now
25703         # once we fully implement dir layout, we can drop this
25704         umount_client $MOUNT || error "umount failed"
25705         mount_client $MOUNT || error "mount failed"
25706
25707         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25708         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25709         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25710
25711         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25712                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25713                         error "create crush2 dir $tdir/hashdir/d3 failed"
25714                 $LFS find -H crush2 $DIR/$tdir/hashdir
25715                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25716                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25717
25718                 # mkdir with an invalid hash type (hash=fail_val) from client
25719                 # should be replaced on MDS with a valid (default) hash type
25720                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25721                 $LCTL set_param fail_loc=0x1901 fail_val=99
25722                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25723
25724                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25725                 local expect=$(do_facet mds1 \
25726                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25727                 [[ $hash == $expect ]] ||
25728                         error "d99 hash '$hash' != expected hash '$expect'"
25729         fi
25730
25731         #set the stripe to be unknown hash type on read
25732         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25733         $LCTL set_param fail_loc=0x1901 fail_val=99
25734         for ((i = 0; i < 10; i++)); do
25735                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25736                         error "stat f-$i failed"
25737                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25738         done
25739
25740         touch $DIR/$tdir/striped_dir/f0 &&
25741                 error "create under striped dir with unknown hash should fail"
25742
25743         $LCTL set_param fail_loc=0
25744
25745         umount_client $MOUNT || error "umount failed"
25746         mount_client $MOUNT || error "mount failed"
25747
25748         return 0
25749 }
25750 run_test 300i "client handle unknown hash type striped directory"
25751
25752 test_300j() {
25753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25755         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25756                 skip "Need MDS version at least 2.7.55"
25757
25758         local stripe_count
25759         local file
25760
25761         mkdir $DIR/$tdir
25762
25763         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25764         $LCTL set_param fail_loc=0x1702
25765         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25766                 error "set striped dir error"
25767
25768         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25769                 error "create files under striped dir failed"
25770
25771         $LCTL set_param fail_loc=0
25772
25773         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25774
25775         return 0
25776 }
25777 run_test 300j "test large update record"
25778
25779 test_300k() {
25780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25782         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25783                 skip "Need MDS version at least 2.7.55"
25784
25785         # this test needs a huge transaction
25786         local kb
25787         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25788              osd*.$FSNAME-MDT0000.kbytestotal")
25789         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25790
25791         local stripe_count
25792         local file
25793
25794         mkdir $DIR/$tdir
25795
25796         #define OBD_FAIL_LARGE_STRIPE   0x1703
25797         $LCTL set_param fail_loc=0x1703
25798         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25799                 error "set striped dir error"
25800         $LCTL set_param fail_loc=0
25801
25802         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25803                 error "getstripeddir fails"
25804         rm -rf $DIR/$tdir/striped_dir ||
25805                 error "unlink striped dir fails"
25806
25807         return 0
25808 }
25809 run_test 300k "test large striped directory"
25810
25811 test_300l() {
25812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25814         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25815                 skip "Need MDS version at least 2.7.55"
25816
25817         local stripe_index
25818
25819         test_mkdir -p $DIR/$tdir/striped_dir
25820         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25821                         error "chown $RUNAS_ID failed"
25822         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25823                 error "set default striped dir failed"
25824
25825         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25826         $LCTL set_param fail_loc=0x80000158
25827         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25828
25829         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25830         [ $stripe_index -eq 1 ] ||
25831                 error "expect 1 get $stripe_index for $dir"
25832 }
25833 run_test 300l "non-root user to create dir under striped dir with stale layout"
25834
25835 test_300m() {
25836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25837         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25838         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25839                 skip "Need MDS version at least 2.7.55"
25840
25841         mkdir -p $DIR/$tdir/striped_dir
25842         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25843                 error "set default stripes dir error"
25844
25845         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25846
25847         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25848         [ $stripe_count -eq 0 ] ||
25849                         error "expect 0 get $stripe_count for a"
25850
25851         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25852                 error "set default stripes dir error"
25853
25854         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25855
25856         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25857         [ $stripe_count -eq 0 ] ||
25858                         error "expect 0 get $stripe_count for b"
25859
25860         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25861                 error "set default stripes dir error"
25862
25863         mkdir $DIR/$tdir/striped_dir/c &&
25864                 error "default stripe_index is invalid, mkdir c should fails"
25865
25866         rm -rf $DIR/$tdir || error "rmdir fails"
25867 }
25868 run_test 300m "setstriped directory on single MDT FS"
25869
25870 cleanup_300n() {
25871         local list=$(comma_list $(mdts_nodes))
25872
25873         trap 0
25874         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25875 }
25876
25877 test_300n() {
25878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25880         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25881                 skip "Need MDS version at least 2.7.55"
25882         remote_mds_nodsh && skip "remote MDS with nodsh"
25883
25884         local stripe_index
25885         local list=$(comma_list $(mdts_nodes))
25886
25887         trap cleanup_300n RETURN EXIT
25888         mkdir -p $DIR/$tdir
25889         chmod 777 $DIR/$tdir
25890         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25891                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25892                 error "create striped dir succeeds with gid=0"
25893
25894         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25895         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25896                 error "create striped dir fails with gid=-1"
25897
25898         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25899         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25900                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25901                 error "set default striped dir succeeds with gid=0"
25902
25903
25904         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25905         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25906                 error "set default striped dir fails with gid=-1"
25907
25908
25909         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25910         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25911                                         error "create test_dir fails"
25912         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25913                                         error "create test_dir1 fails"
25914         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25915                                         error "create test_dir2 fails"
25916         cleanup_300n
25917 }
25918 run_test 300n "non-root user to create dir under striped dir with default EA"
25919
25920 test_300o() {
25921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25922         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25923         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25924                 skip "Need MDS version at least 2.7.55"
25925
25926         local numfree1
25927         local numfree2
25928
25929         mkdir -p $DIR/$tdir
25930
25931         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25932         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25933         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25934                 skip "not enough free inodes $numfree1 $numfree2"
25935         fi
25936
25937         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25938         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25939         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25940                 skip "not enough free space $numfree1 $numfree2"
25941         fi
25942
25943         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25944                 error "setdirstripe fails"
25945
25946         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25947                 error "create dirs fails"
25948
25949         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25950         ls $DIR/$tdir/striped_dir > /dev/null ||
25951                 error "ls striped dir fails"
25952         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25953                 error "unlink big striped dir fails"
25954 }
25955 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25956
25957 test_300p() {
25958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25960         remote_mds_nodsh && skip "remote MDS with nodsh"
25961
25962         mkdir_on_mdt0 $DIR/$tdir
25963
25964         #define OBD_FAIL_OUT_ENOSPC     0x1704
25965         do_facet mds2 lctl set_param fail_loc=0x80001704
25966         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25967                  && error "create striped directory should fail"
25968
25969         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25970
25971         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25972         true
25973 }
25974 run_test 300p "create striped directory without space"
25975
25976 test_300q() {
25977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25979
25980         local fd=$(free_fd)
25981         local cmd="exec $fd<$tdir"
25982         cd $DIR
25983         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25984         eval $cmd
25985         cmd="exec $fd<&-"
25986         trap "eval $cmd" EXIT
25987         cd $tdir || error "cd $tdir fails"
25988         rmdir  ../$tdir || error "rmdir $tdir fails"
25989         mkdir local_dir && error "create dir succeeds"
25990         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25991         eval $cmd
25992         return 0
25993 }
25994 run_test 300q "create remote directory under orphan directory"
25995
25996 test_300r() {
25997         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25998                 skip "Need MDS version at least 2.7.55" && return
25999         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26000
26001         mkdir $DIR/$tdir
26002
26003         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26004                 error "set striped dir error"
26005
26006         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26007                 error "getstripeddir fails"
26008
26009         local stripe_count
26010         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26011                       awk '/lmv_stripe_count:/ { print $2 }')
26012
26013         [ $MDSCOUNT -ne $stripe_count ] &&
26014                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26015
26016         rm -rf $DIR/$tdir/striped_dir ||
26017                 error "unlink striped dir fails"
26018 }
26019 run_test 300r "test -1 striped directory"
26020
26021 test_300s_helper() {
26022         local count=$1
26023
26024         local stripe_dir=$DIR/$tdir/striped_dir.$count
26025
26026         $LFS mkdir -c $count $stripe_dir ||
26027                 error "lfs mkdir -c error"
26028
26029         $LFS getdirstripe $stripe_dir ||
26030                 error "lfs getdirstripe fails"
26031
26032         local stripe_count
26033         stripe_count=$($LFS getdirstripe $stripe_dir |
26034                       awk '/lmv_stripe_count:/ { print $2 }')
26035
26036         [ $count -ne $stripe_count ] &&
26037                 error_noexit "bad stripe count $stripe_count expected $count"
26038
26039         local dupe_stripes
26040         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26041                 awk '/0x/ {count[$1] += 1}; END {
26042                         for (idx in count) {
26043                                 if (count[idx]>1) {
26044                                         print "index " idx " count " count[idx]
26045                                 }
26046                         }
26047                 }')
26048
26049         if [[ -n "$dupe_stripes" ]] ; then
26050                 lfs getdirstripe $stripe_dir
26051                 error_noexit "Dupe MDT above: $dupe_stripes "
26052         fi
26053
26054         rm -rf $stripe_dir ||
26055                 error_noexit "unlink $stripe_dir fails"
26056 }
26057
26058 test_300s() {
26059         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26060                 skip "Need MDS version at least 2.7.55" && return
26061         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26062
26063         mkdir $DIR/$tdir
26064         for count in $(seq 2 $MDSCOUNT); do
26065                 test_300s_helper $count
26066         done
26067 }
26068 run_test 300s "test lfs mkdir -c without -i"
26069
26070 test_300t() {
26071         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26072                 skip "need MDS 2.14.55 or later"
26073         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26074
26075         local testdir="$DIR/$tdir/striped_dir"
26076         local dir1=$testdir/dir1
26077         local dir2=$testdir/dir2
26078
26079         mkdir -p $testdir
26080
26081         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26082                 error "failed to set default stripe count for $testdir"
26083
26084         mkdir $dir1
26085         local stripe_count=$($LFS getdirstripe -c $dir1)
26086
26087         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26088
26089         local max_count=$((MDSCOUNT - 1))
26090         local mdts=$(comma_list $(mdts_nodes))
26091
26092         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26093         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26094
26095         mkdir $dir2
26096         stripe_count=$($LFS getdirstripe -c $dir2)
26097
26098         (( $stripe_count == $max_count )) || error "wrong stripe count"
26099 }
26100 run_test 300t "test max_mdt_stripecount"
26101
26102 prepare_remote_file() {
26103         mkdir $DIR/$tdir/src_dir ||
26104                 error "create remote source failed"
26105
26106         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26107                  error "cp to remote source failed"
26108         touch $DIR/$tdir/src_dir/a
26109
26110         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26111                 error "create remote target dir failed"
26112
26113         touch $DIR/$tdir/tgt_dir/b
26114
26115         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26116                 error "rename dir cross MDT failed!"
26117
26118         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26119                 error "src_child still exists after rename"
26120
26121         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26122                 error "missing file(a) after rename"
26123
26124         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26125                 error "diff after rename"
26126 }
26127
26128 test_310a() {
26129         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26131
26132         local remote_file=$DIR/$tdir/tgt_dir/b
26133
26134         mkdir -p $DIR/$tdir
26135
26136         prepare_remote_file || error "prepare remote file failed"
26137
26138         #open-unlink file
26139         $OPENUNLINK $remote_file $remote_file ||
26140                 error "openunlink $remote_file failed"
26141         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26142 }
26143 run_test 310a "open unlink remote file"
26144
26145 test_310b() {
26146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26148
26149         local remote_file=$DIR/$tdir/tgt_dir/b
26150
26151         mkdir -p $DIR/$tdir
26152
26153         prepare_remote_file || error "prepare remote file failed"
26154
26155         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26156         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26157         $CHECKSTAT -t file $remote_file || error "check file failed"
26158 }
26159 run_test 310b "unlink remote file with multiple links while open"
26160
26161 test_310c() {
26162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26163         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26164
26165         local remote_file=$DIR/$tdir/tgt_dir/b
26166
26167         mkdir -p $DIR/$tdir
26168
26169         prepare_remote_file || error "prepare remote file failed"
26170
26171         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26172         multiop_bg_pause $remote_file O_uc ||
26173                         error "mulitop failed for remote file"
26174         MULTIPID=$!
26175         $MULTIOP $DIR/$tfile Ouc
26176         kill -USR1 $MULTIPID
26177         wait $MULTIPID
26178 }
26179 run_test 310c "open-unlink remote file with multiple links"
26180
26181 #LU-4825
26182 test_311() {
26183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26184         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26185         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26186                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26187         remote_mds_nodsh && skip "remote MDS with nodsh"
26188
26189         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26190         local mdts=$(comma_list $(mdts_nodes))
26191
26192         mkdir -p $DIR/$tdir
26193         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26194         createmany -o $DIR/$tdir/$tfile. 1000
26195
26196         # statfs data is not real time, let's just calculate it
26197         old_iused=$((old_iused + 1000))
26198
26199         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26200                         osp.*OST0000*MDT0000.create_count")
26201         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26202                                 osp.*OST0000*MDT0000.max_create_count")
26203         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26204
26205         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26206         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26207         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26208
26209         unlinkmany $DIR/$tdir/$tfile. 1000
26210
26211         do_nodes $mdts "$LCTL set_param -n \
26212                         osp.*OST0000*.max_create_count=$max_count"
26213         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26214                 do_nodes $mdts "$LCTL set_param -n \
26215                                 osp.*OST0000*.create_count=$count"
26216         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26217                         grep "=0" && error "create_count is zero"
26218
26219         local new_iused
26220         for i in $(seq 120); do
26221                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26222                 # system may be too busy to destroy all objs in time, use
26223                 # a somewhat small value to not fail autotest
26224                 [ $((old_iused - new_iused)) -gt 400 ] && break
26225                 sleep 1
26226         done
26227
26228         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26229         [ $((old_iused - new_iused)) -gt 400 ] ||
26230                 error "objs not destroyed after unlink"
26231 }
26232 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26233
26234 zfs_get_objid()
26235 {
26236         local ost=$1
26237         local tf=$2
26238         local fid=($($LFS getstripe $tf | grep 0x))
26239         local seq=${fid[3]#0x}
26240         local objid=${fid[1]}
26241
26242         local vdevdir=$(dirname $(facet_vdevice $ost))
26243         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26244         local zfs_zapid=$(do_facet $ost $cmd |
26245                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26246                           awk '/Object/{getline; print $1}')
26247         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26248                           awk "/$objid = /"'{printf $3}')
26249
26250         echo $zfs_objid
26251 }
26252
26253 zfs_object_blksz() {
26254         local ost=$1
26255         local objid=$2
26256
26257         local vdevdir=$(dirname $(facet_vdevice $ost))
26258         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26259         local blksz=$(do_facet $ost $cmd $objid |
26260                       awk '/dblk/{getline; printf $4}')
26261
26262         case "${blksz: -1}" in
26263                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26264                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26265                 *) ;;
26266         esac
26267
26268         echo $blksz
26269 }
26270
26271 test_312() { # LU-4856
26272         remote_ost_nodsh && skip "remote OST with nodsh"
26273         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26274
26275         local max_blksz=$(do_facet ost1 \
26276                           $ZFS get -p recordsize $(facet_device ost1) |
26277                           awk '!/VALUE/{print $3}')
26278         local tf=$DIR/$tfile
26279
26280         $LFS setstripe -c1 $tf
26281         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26282
26283         # Get ZFS object id
26284         local zfs_objid=$(zfs_get_objid $facet $tf)
26285         # block size change by sequential overwrite
26286         local bs
26287
26288         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26289                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26290
26291                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26292                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26293         done
26294         rm -f $tf
26295
26296         $LFS setstripe -c1 $tf
26297         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26298
26299         # block size change by sequential append write
26300         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26301         zfs_objid=$(zfs_get_objid $facet $tf)
26302         local count
26303
26304         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26305                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26306                         oflag=sync conv=notrunc
26307
26308                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26309                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26310                         error "blksz error, actual $blksz, " \
26311                                 "expected: 2 * $count * $PAGE_SIZE"
26312         done
26313         rm -f $tf
26314
26315         # random write
26316         $LFS setstripe -c1 $tf
26317         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26318         zfs_objid=$(zfs_get_objid $facet $tf)
26319
26320         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26321         blksz=$(zfs_object_blksz $facet $zfs_objid)
26322         (( blksz == PAGE_SIZE )) ||
26323                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26324
26325         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26326         blksz=$(zfs_object_blksz $facet $zfs_objid)
26327         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26328
26329         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26330         blksz=$(zfs_object_blksz $facet $zfs_objid)
26331         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26332 }
26333 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26334
26335 test_313() {
26336         remote_ost_nodsh && skip "remote OST with nodsh"
26337
26338         local file=$DIR/$tfile
26339
26340         rm -f $file
26341         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26342
26343         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26344         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26345         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26346                 error "write should failed"
26347         do_facet ost1 "$LCTL set_param fail_loc=0"
26348         rm -f $file
26349 }
26350 run_test 313 "io should fail after last_rcvd update fail"
26351
26352 test_314() {
26353         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26354
26355         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26356         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26357         rm -f $DIR/$tfile
26358         wait_delete_completed
26359         do_facet ost1 "$LCTL set_param fail_loc=0"
26360 }
26361 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26362
26363 test_315() { # LU-618
26364         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26365
26366         local file=$DIR/$tfile
26367         rm -f $file
26368
26369         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26370                 error "multiop file write failed"
26371         $MULTIOP $file oO_RDONLY:r4063232_c &
26372         PID=$!
26373
26374         sleep 2
26375
26376         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26377         kill -USR1 $PID
26378
26379         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26380         rm -f $file
26381 }
26382 run_test 315 "read should be accounted"
26383
26384 test_316() {
26385         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26386         large_xattr_enabled || skip "ea_inode feature disabled"
26387
26388         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26389         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26390         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26391         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26392
26393         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26394 }
26395 run_test 316 "lfs migrate of file with large_xattr enabled"
26396
26397 test_317() {
26398         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26399                 skip "Need MDS version at least 2.11.53"
26400         if [ "$ost1_FSTYPE" == "zfs" ]; then
26401                 skip "LU-10370: no implementation for ZFS"
26402         fi
26403
26404         local trunc_sz
26405         local grant_blk_size
26406
26407         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26408                         awk '/grant_block_size:/ { print $2; exit; }')
26409         #
26410         # Create File of size 5M. Truncate it to below size's and verify
26411         # blocks count.
26412         #
26413         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26414                 error "Create file $DIR/$tfile failed"
26415         stack_trap "rm -f $DIR/$tfile" EXIT
26416
26417         for trunc_sz in 2097152 4097 4000 509 0; do
26418                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26419                         error "truncate $tfile to $trunc_sz failed"
26420                 local sz=$(stat --format=%s $DIR/$tfile)
26421                 local blk=$(stat --format=%b $DIR/$tfile)
26422                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26423                                      grant_blk_size) * 8))
26424
26425                 if [[ $blk -ne $trunc_blk ]]; then
26426                         $(which stat) $DIR/$tfile
26427                         error "Expected Block $trunc_blk got $blk for $tfile"
26428                 fi
26429
26430                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26431                         error "Expected Size $trunc_sz got $sz for $tfile"
26432         done
26433
26434         #
26435         # sparse file test
26436         # Create file with a hole and write actual 65536 bytes which aligned
26437         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26438         #
26439         local bs=65536
26440         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26441                 error "Create file : $DIR/$tfile"
26442
26443         #
26444         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26445         # blocks. The block count must drop to 8.
26446         #
26447         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26448                 ((bs - grant_blk_size) + 1)))
26449         $TRUNCATE $DIR/$tfile $trunc_sz ||
26450                 error "truncate $tfile to $trunc_sz failed"
26451
26452         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26453         sz=$(stat --format=%s $DIR/$tfile)
26454         blk=$(stat --format=%b $DIR/$tfile)
26455
26456         if [[ $blk -ne $trunc_bsz ]]; then
26457                 $(which stat) $DIR/$tfile
26458                 error "Expected Block $trunc_bsz got $blk for $tfile"
26459         fi
26460
26461         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26462                 error "Expected Size $trunc_sz got $sz for $tfile"
26463 }
26464 run_test 317 "Verify blocks get correctly update after truncate"
26465
26466 test_318() {
26467         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26468         local old_max_active=$($LCTL get_param -n \
26469                             ${llite_name}.max_read_ahead_async_active \
26470                             2>/dev/null)
26471
26472         $LCTL set_param llite.*.max_read_ahead_async_active=256
26473         local max_active=$($LCTL get_param -n \
26474                            ${llite_name}.max_read_ahead_async_active \
26475                            2>/dev/null)
26476         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26477
26478         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26479                 error "set max_read_ahead_async_active should succeed"
26480
26481         $LCTL set_param llite.*.max_read_ahead_async_active=512
26482         max_active=$($LCTL get_param -n \
26483                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26484         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26485
26486         # restore @max_active
26487         [ $old_max_active -ne 0 ] && $LCTL set_param \
26488                 llite.*.max_read_ahead_async_active=$old_max_active
26489
26490         local old_threshold=$($LCTL get_param -n \
26491                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26492         local max_per_file_mb=$($LCTL get_param -n \
26493                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26494
26495         local invalid=$(($max_per_file_mb + 1))
26496         $LCTL set_param \
26497                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26498                         && error "set $invalid should fail"
26499
26500         local valid=$(($invalid - 1))
26501         $LCTL set_param \
26502                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26503                         error "set $valid should succeed"
26504         local threshold=$($LCTL get_param -n \
26505                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26506         [ $threshold -eq $valid ] || error \
26507                 "expect threshold $valid got $threshold"
26508         $LCTL set_param \
26509                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26510 }
26511 run_test 318 "Verify async readahead tunables"
26512
26513 test_319() {
26514         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26515
26516         local before=$(date +%s)
26517         local evict
26518         local mdir=$DIR/$tdir
26519         local file=$mdir/xxx
26520
26521         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26522         touch $file
26523
26524 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26525         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26526         $LFS migrate -m1 $mdir &
26527
26528         sleep 1
26529         dd if=$file of=/dev/null
26530         wait
26531         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26532           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26533
26534         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26535 }
26536 run_test 319 "lost lease lock on migrate error"
26537
26538 test_398a() { # LU-4198
26539         local ost1_imp=$(get_osc_import_name client ost1)
26540         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26541                          cut -d'.' -f2)
26542
26543         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26544         stack_trap "rm -f $DIR/$tfile"
26545         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26546
26547         # request a new lock on client
26548         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26549
26550         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26551         local lock_count=$($LCTL get_param -n \
26552                            ldlm.namespaces.$imp_name.lru_size)
26553         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26554
26555         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26556
26557         # no lock cached, should use lockless DIO and not enqueue new lock
26558         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26559         lock_count=$($LCTL get_param -n \
26560                      ldlm.namespaces.$imp_name.lru_size)
26561         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26562
26563         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26564
26565         # no lock cached, should use locked DIO append
26566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26567                 conv=notrunc || error "DIO append failed"
26568         lock_count=$($LCTL get_param -n \
26569                      ldlm.namespaces.$imp_name.lru_size)
26570         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26571 }
26572 run_test 398a "direct IO should cancel lock otherwise lockless"
26573
26574 test_398b() { # LU-4198
26575         local before=$(date +%s)
26576         local njobs=4
26577         local size=48
26578
26579         which fio || skip_env "no fio installed"
26580         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26581         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26582
26583         # Single page, multiple pages, stripe size, 4*stripe size
26584         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26585                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26586                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26587                         --numjobs=$njobs --fallocate=none \
26588                         --iodepth=16 --allow_file_create=0 \
26589                         --size=$((size/njobs))M \
26590                         --filename=$DIR/$tfile &
26591                 bg_pid=$!
26592
26593                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26594                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26595                         --numjobs=$njobs --fallocate=none \
26596                         --iodepth=16 --allow_file_create=0 \
26597                         --size=$((size/njobs))M \
26598                         --filename=$DIR/$tfile || true
26599                 wait $bg_pid
26600         done
26601
26602         evict=$(do_facet client $LCTL get_param \
26603                 osc.$FSNAME-OST*-osc-*/state |
26604             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26605
26606         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26607                 (do_facet client $LCTL get_param \
26608                         osc.$FSNAME-OST*-osc-*/state;
26609                     error "eviction happened: $evict before:$before")
26610
26611         rm -f $DIR/$tfile
26612 }
26613 run_test 398b "DIO and buffer IO race"
26614
26615 test_398c() { # LU-4198
26616         local ost1_imp=$(get_osc_import_name client ost1)
26617         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26618                          cut -d'.' -f2)
26619
26620         which fio || skip_env "no fio installed"
26621
26622         saved_debug=$($LCTL get_param -n debug)
26623         $LCTL set_param debug=0
26624
26625         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26626         ((size /= 1024)) # by megabytes
26627         ((size /= 2)) # write half of the OST at most
26628         [ $size -gt 40 ] && size=40 #reduce test time anyway
26629
26630         $LFS setstripe -c 1 $DIR/$tfile
26631
26632         # it seems like ldiskfs reserves more space than necessary if the
26633         # writing blocks are not mapped, so it extends the file firstly
26634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26635         cancel_lru_locks osc
26636
26637         # clear and verify rpc_stats later
26638         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26639
26640         local njobs=4
26641         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26642         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26643                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26644                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26645                 --filename=$DIR/$tfile
26646         [ $? -eq 0 ] || error "fio write error"
26647
26648         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26649                 error "Locks were requested while doing AIO"
26650
26651         # get the percentage of 1-page I/O
26652         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26653                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26654                 awk '{print $7}')
26655         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26656
26657         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26658         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26659                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26660                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26661                 --filename=$DIR/$tfile
26662         [ $? -eq 0 ] || error "fio mixed read write error"
26663
26664         echo "AIO with large block size ${size}M"
26665         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26666                 --numjobs=1 --fallocate=none --ioengine=libaio \
26667                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26668                 --filename=$DIR/$tfile
26669         [ $? -eq 0 ] || error "fio large block size failed"
26670
26671         rm -f $DIR/$tfile
26672         $LCTL set_param debug="$saved_debug"
26673 }
26674 run_test 398c "run fio to test AIO"
26675
26676 test_398d() { #  LU-13846
26677         which aiocp || skip_env "no aiocp installed"
26678         local aio_file=$DIR/$tfile.aio
26679
26680         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26681
26682         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26683         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26684         stack_trap "rm -f $DIR/$tfile $aio_file"
26685
26686         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26687
26688         # test memory unaligned aio
26689         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26690                 error "unaligned aio failed"
26691         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26692
26693         rm -f $DIR/$tfile $aio_file
26694 }
26695 run_test 398d "run aiocp to verify block size > stripe size"
26696
26697 test_398e() {
26698         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26699         touch $DIR/$tfile.new
26700         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26701 }
26702 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26703
26704 test_398f() { #  LU-14687
26705         which aiocp || skip_env "no aiocp installed"
26706         local aio_file=$DIR/$tfile.aio
26707
26708         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26709
26710         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26711         stack_trap "rm -f $DIR/$tfile $aio_file"
26712
26713         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26714         $LCTL set_param fail_loc=0x1418
26715         # make sure we don't crash and fail properly
26716         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26717                 error "aio with page allocation failure succeeded"
26718         $LCTL set_param fail_loc=0
26719         diff $DIR/$tfile $aio_file
26720         [[ $? != 0 ]] || error "no diff after failed aiocp"
26721 }
26722 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26723
26724 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26725 # stripe and i/o size must be > stripe size
26726 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26727 # single RPC in flight.  This test shows async DIO submission is working by
26728 # showing multiple RPCs in flight.
26729 test_398g() { #  LU-13798
26730         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26731
26732         # We need to do some i/o first to acquire enough grant to put our RPCs
26733         # in flight; otherwise a new connection may not have enough grant
26734         # available
26735         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26736                 error "parallel dio failed"
26737         stack_trap "rm -f $DIR/$tfile"
26738
26739         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26740         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26741         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26742         stack_trap "$LCTL set_param -n $pages_per_rpc"
26743
26744         # Recreate file so it's empty
26745         rm -f $DIR/$tfile
26746         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26747         #Pause rpc completion to guarantee we see multiple rpcs in flight
26748         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26749         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26750         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26751
26752         # Clear rpc stats
26753         $LCTL set_param osc.*.rpc_stats=c
26754
26755         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26756                 error "parallel dio failed"
26757         stack_trap "rm -f $DIR/$tfile"
26758
26759         $LCTL get_param osc.*-OST0000-*.rpc_stats
26760         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26761                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26762                 grep "8:" | awk '{print $8}')
26763         # We look at the "8 rpcs in flight" field, and verify A) it is present
26764         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26765         # as expected for an 8M DIO to a file with 1M stripes.
26766         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26767
26768         # Verify turning off parallel dio works as expected
26769         # Clear rpc stats
26770         $LCTL set_param osc.*.rpc_stats=c
26771         $LCTL set_param llite.*.parallel_dio=0
26772         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26773
26774         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26775                 error "dio with parallel dio disabled failed"
26776
26777         # Ideally, we would see only one RPC in flight here, but there is an
26778         # unavoidable race between i/o completion and RPC in flight counting,
26779         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26780         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26781         # So instead we just verify it's always < 8.
26782         $LCTL get_param osc.*-OST0000-*.rpc_stats
26783         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26784                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26785                 grep '^$' -B1 | grep . | awk '{print $1}')
26786         [ $ret != "8:" ] ||
26787                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26788 }
26789 run_test 398g "verify parallel dio async RPC submission"
26790
26791 test_398h() { #  LU-13798
26792         local dio_file=$DIR/$tfile.dio
26793
26794         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26795
26796         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26797         stack_trap "rm -f $DIR/$tfile $dio_file"
26798
26799         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26800                 error "parallel dio failed"
26801         diff $DIR/$tfile $dio_file
26802         [[ $? == 0 ]] || error "file diff after aiocp"
26803 }
26804 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26805
26806 test_398i() { #  LU-13798
26807         local dio_file=$DIR/$tfile.dio
26808
26809         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26810
26811         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26812         stack_trap "rm -f $DIR/$tfile $dio_file"
26813
26814         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26815         $LCTL set_param fail_loc=0x1418
26816         # make sure we don't crash and fail properly
26817         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26818                 error "parallel dio page allocation failure succeeded"
26819         diff $DIR/$tfile $dio_file
26820         [[ $? != 0 ]] || error "no diff after failed aiocp"
26821 }
26822 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26823
26824 test_398j() { #  LU-13798
26825         # Stripe size > RPC size but less than i/o size tests split across
26826         # stripes and RPCs for individual i/o op
26827         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26828
26829         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26830         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26831         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26832         stack_trap "$LCTL set_param -n $pages_per_rpc"
26833
26834         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26835                 error "parallel dio write failed"
26836         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26837
26838         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26839                 error "parallel dio read failed"
26840         diff $DIR/$tfile $DIR/$tfile.2
26841         [[ $? == 0 ]] || error "file diff after parallel dio read"
26842 }
26843 run_test 398j "test parallel dio where stripe size > rpc_size"
26844
26845 test_398k() { #  LU-13798
26846         wait_delete_completed
26847         wait_mds_ost_sync
26848
26849         # 4 stripe file; we will cause out of space on OST0
26850         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26851
26852         # Fill OST0 (if it's not too large)
26853         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26854                    head -n1)
26855         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26856                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26857         fi
26858         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26859         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26860                 error "dd should fill OST0"
26861         stack_trap "rm -f $DIR/$tfile.1"
26862
26863         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26864         err=$?
26865
26866         ls -la $DIR/$tfile
26867         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26868                 error "file is not 0 bytes in size"
26869
26870         # dd above should not succeed, but don't error until here so we can
26871         # get debug info above
26872         [[ $err != 0 ]] ||
26873                 error "parallel dio write with enospc succeeded"
26874         stack_trap "rm -f $DIR/$tfile"
26875 }
26876 run_test 398k "test enospc on first stripe"
26877
26878 test_398l() { #  LU-13798
26879         wait_delete_completed
26880         wait_mds_ost_sync
26881
26882         # 4 stripe file; we will cause out of space on OST0
26883         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26884         # happens on the second i/o chunk we issue
26885         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26886
26887         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26888         stack_trap "rm -f $DIR/$tfile"
26889
26890         # Fill OST0 (if it's not too large)
26891         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26892                    head -n1)
26893         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26894                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26895         fi
26896         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26897         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26898                 error "dd should fill OST0"
26899         stack_trap "rm -f $DIR/$tfile.1"
26900
26901         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26902         err=$?
26903         stack_trap "rm -f $DIR/$tfile.2"
26904
26905         # Check that short write completed as expected
26906         ls -la $DIR/$tfile.2
26907         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26908                 error "file is not 1M in size"
26909
26910         # dd above should not succeed, but don't error until here so we can
26911         # get debug info above
26912         [[ $err != 0 ]] ||
26913                 error "parallel dio write with enospc succeeded"
26914
26915         # Truncate source file to same length as output file and diff them
26916         $TRUNCATE $DIR/$tfile 1048576
26917         diff $DIR/$tfile $DIR/$tfile.2
26918         [[ $? == 0 ]] || error "data incorrect after short write"
26919 }
26920 run_test 398l "test enospc on intermediate stripe/RPC"
26921
26922 test_398m() { #  LU-13798
26923         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26924
26925         # Set up failure on OST0, the first stripe:
26926         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26927         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26928         # OST0 is on ost1, OST1 is on ost2.
26929         # So this fail_val specifies OST0
26930         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26931         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26932
26933         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26934                 error "parallel dio write with failure on first stripe succeeded"
26935         stack_trap "rm -f $DIR/$tfile"
26936         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26937
26938         # Place data in file for read
26939         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26940                 error "parallel dio write failed"
26941
26942         # Fail read on OST0, first stripe
26943         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26944         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26945         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26946                 error "parallel dio read with error on first stripe succeeded"
26947         rm -f $DIR/$tfile.2
26948         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26949
26950         # Switch to testing on OST1, second stripe
26951         # Clear file contents, maintain striping
26952         echo > $DIR/$tfile
26953         # Set up failure on OST1, second stripe:
26954         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26955         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26956
26957         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26958                 error "parallel dio write with failure on second stripe succeeded"
26959         stack_trap "rm -f $DIR/$tfile"
26960         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26961
26962         # Place data in file for read
26963         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26964                 error "parallel dio write failed"
26965
26966         # Fail read on OST1, second stripe
26967         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26968         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26969         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26970                 error "parallel dio read with error on second stripe succeeded"
26971         rm -f $DIR/$tfile.2
26972         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26973 }
26974 run_test 398m "test RPC failures with parallel dio"
26975
26976 # Parallel submission of DIO should not cause problems for append, but it's
26977 # important to verify.
26978 test_398n() { #  LU-13798
26979         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26980
26981         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26982                 error "dd to create source file failed"
26983         stack_trap "rm -f $DIR/$tfile"
26984
26985         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26986                 error "parallel dio write with failure on second stripe succeeded"
26987         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26988         diff $DIR/$tfile $DIR/$tfile.1
26989         [[ $? == 0 ]] || error "data incorrect after append"
26990
26991 }
26992 run_test 398n "test append with parallel DIO"
26993
26994 test_398o() {
26995         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26996 }
26997 run_test 398o "right kms with DIO"
26998
26999 test_398p()
27000 {
27001         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27002         which aiocp || skip_env "no aiocp installed"
27003
27004         local stripe_size=$((1024 * 1024)) #1 MiB
27005         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27006         local file_size=$((25 * stripe_size))
27007
27008         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27009         stack_trap "rm -f $DIR/$tfile*"
27010         # Just a bit bigger than the largest size in the test set below
27011         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27012                 error "buffered i/o to create file failed"
27013
27014         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27015                 $((stripe_size * 4)); do
27016
27017                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27018
27019                 echo "bs: $bs, file_size $file_size"
27020                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27021                         $DIR/$tfile.1 $DIR/$tfile.2 &
27022                 pid_dio1=$!
27023                 # Buffered I/O with similar but not the same block size
27024                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27025                         conv=notrunc &
27026                 pid_bio2=$!
27027                 wait $pid_dio1
27028                 rc1=$?
27029                 wait $pid_bio2
27030                 rc2=$?
27031                 if (( rc1 != 0 )); then
27032                         error "aio copy 1 w/bsize $bs failed: $rc1"
27033                 fi
27034                 if (( rc2 != 0 )); then
27035                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27036                 fi
27037
27038                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27039                         error "size incorrect"
27040                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27041                         error "files differ, bsize $bs"
27042                 rm -f $DIR/$tfile.2
27043         done
27044 }
27045 run_test 398p "race aio with buffered i/o"
27046
27047 test_398q()
27048 {
27049         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27050
27051         local stripe_size=$((1024 * 1024)) #1 MiB
27052         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27053         local file_size=$((25 * stripe_size))
27054
27055         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27056         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27057
27058         # Just a bit bigger than the largest size in the test set below
27059         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27060                 error "buffered i/o to create file failed"
27061
27062         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27063                 $((stripe_size * 4)); do
27064
27065                 echo "bs: $bs, file_size $file_size"
27066                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27067                         conv=notrunc oflag=direct iflag=direct &
27068                 pid_dio1=$!
27069                 # Buffered I/O with similar but not the same block size
27070                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27071                         conv=notrunc &
27072                 pid_bio2=$!
27073                 wait $pid_dio1
27074                 rc1=$?
27075                 wait $pid_bio2
27076                 rc2=$?
27077                 if (( rc1 != 0 )); then
27078                         error "dio copy 1 w/bsize $bs failed: $rc1"
27079                 fi
27080                 if (( rc2 != 0 )); then
27081                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27082                 fi
27083
27084                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27085                         error "size incorrect"
27086                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27087                         error "files differ, bsize $bs"
27088         done
27089
27090         rm -f $DIR/$tfile*
27091 }
27092 run_test 398q "race dio with buffered i/o"
27093
27094 test_fake_rw() {
27095         local read_write=$1
27096         if [ "$read_write" = "write" ]; then
27097                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27098         elif [ "$read_write" = "read" ]; then
27099                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27100         else
27101                 error "argument error"
27102         fi
27103
27104         # turn off debug for performance testing
27105         local saved_debug=$($LCTL get_param -n debug)
27106         $LCTL set_param debug=0
27107
27108         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27109
27110         # get ost1 size - $FSNAME-OST0000
27111         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27112         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27113         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27114
27115         if [ "$read_write" = "read" ]; then
27116                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27117         fi
27118
27119         local start_time=$(date +%s.%N)
27120         $dd_cmd bs=1M count=$blocks oflag=sync ||
27121                 error "real dd $read_write error"
27122         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27123
27124         if [ "$read_write" = "write" ]; then
27125                 rm -f $DIR/$tfile
27126         fi
27127
27128         # define OBD_FAIL_OST_FAKE_RW           0x238
27129         do_facet ost1 $LCTL set_param fail_loc=0x238
27130
27131         local start_time=$(date +%s.%N)
27132         $dd_cmd bs=1M count=$blocks oflag=sync ||
27133                 error "fake dd $read_write error"
27134         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27135
27136         if [ "$read_write" = "write" ]; then
27137                 # verify file size
27138                 cancel_lru_locks osc
27139                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27140                         error "$tfile size not $blocks MB"
27141         fi
27142         do_facet ost1 $LCTL set_param fail_loc=0
27143
27144         echo "fake $read_write $duration_fake vs. normal $read_write" \
27145                 "$duration in seconds"
27146         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27147                 error_not_in_vm "fake write is slower"
27148
27149         $LCTL set_param -n debug="$saved_debug"
27150         rm -f $DIR/$tfile
27151 }
27152 test_399a() { # LU-7655 for OST fake write
27153         remote_ost_nodsh && skip "remote OST with nodsh"
27154
27155         test_fake_rw write
27156 }
27157 run_test 399a "fake write should not be slower than normal write"
27158
27159 test_399b() { # LU-8726 for OST fake read
27160         remote_ost_nodsh && skip "remote OST with nodsh"
27161         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27162                 skip_env "ldiskfs only test"
27163         fi
27164
27165         test_fake_rw read
27166 }
27167 run_test 399b "fake read should not be slower than normal read"
27168
27169 test_400a() { # LU-1606, was conf-sanity test_74
27170         if ! which $CC > /dev/null 2>&1; then
27171                 skip_env "$CC is not installed"
27172         fi
27173
27174         local extra_flags=''
27175         local out=$TMP/$tfile
27176         local prefix=/usr/include/lustre
27177         local prog
27178
27179         # Oleg removes .c files in his test rig so test if any c files exist
27180         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27181                 skip_env "Needed .c test files are missing"
27182
27183         if ! [[ -d $prefix ]]; then
27184                 # Assume we're running in tree and fixup the include path.
27185                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27186                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27187                 extra_flags+=" -L$LUSTRE/utils/.libs"
27188         fi
27189
27190         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27191                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27192                         error "client api broken"
27193         done
27194         rm -f $out
27195 }
27196 run_test 400a "Lustre client api program can compile and link"
27197
27198 test_400b() { # LU-1606, LU-5011
27199         local header
27200         local out=$TMP/$tfile
27201         local prefix=/usr/include/linux/lustre
27202
27203         # We use a hard coded prefix so that this test will not fail
27204         # when run in tree. There are headers in lustre/include/lustre/
27205         # that are not packaged (like lustre_idl.h) and have more
27206         # complicated include dependencies (like config.h and lnet/types.h).
27207         # Since this test about correct packaging we just skip them when
27208         # they don't exist (see below) rather than try to fixup cppflags.
27209
27210         if ! which $CC > /dev/null 2>&1; then
27211                 skip_env "$CC is not installed"
27212         fi
27213
27214         for header in $prefix/*.h; do
27215                 if ! [[ -f "$header" ]]; then
27216                         continue
27217                 fi
27218
27219                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27220                         continue # lustre_ioctl.h is internal header
27221                 fi
27222
27223                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27224                         error "cannot compile '$header'"
27225         done
27226         rm -f $out
27227 }
27228 run_test 400b "packaged headers can be compiled"
27229
27230 test_401a() { #LU-7437
27231         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27232         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27233
27234         #count the number of parameters by "list_param -R"
27235         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27236         #count the number of parameters by listing proc files
27237         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27238         echo "proc_dirs='$proc_dirs'"
27239         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27240         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27241                       sort -u | wc -l)
27242
27243         [ $params -eq $procs ] ||
27244                 error "found $params parameters vs. $procs proc files"
27245
27246         # test the list_param -D option only returns directories
27247         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27248         #count the number of parameters by listing proc directories
27249         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27250                 sort -u | wc -l)
27251
27252         [ $params -eq $procs ] ||
27253                 error "found $params parameters vs. $procs proc files"
27254 }
27255 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27256
27257 test_401b() {
27258         # jobid_var may not allow arbitrary values, so use jobid_name
27259         # if available
27260         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27261                 local testname=jobid_name tmp='testing%p'
27262         else
27263                 local testname=jobid_var tmp=testing
27264         fi
27265
27266         local save=$($LCTL get_param -n $testname)
27267
27268         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27269                 error "no error returned when setting bad parameters"
27270
27271         local jobid_new=$($LCTL get_param -n foe $testname baz)
27272         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27273
27274         $LCTL set_param -n fog=bam $testname=$save bat=fog
27275         local jobid_old=$($LCTL get_param -n foe $testname bag)
27276         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27277 }
27278 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27279
27280 test_401c() {
27281         # jobid_var may not allow arbitrary values, so use jobid_name
27282         # if available
27283         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27284                 local testname=jobid_name
27285         else
27286                 local testname=jobid_var
27287         fi
27288
27289         local jobid_var_old=$($LCTL get_param -n $testname)
27290         local jobid_var_new
27291
27292         $LCTL set_param $testname= &&
27293                 error "no error returned for 'set_param a='"
27294
27295         jobid_var_new=$($LCTL get_param -n $testname)
27296         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27297                 error "$testname was changed by setting without value"
27298
27299         $LCTL set_param $testname &&
27300                 error "no error returned for 'set_param a'"
27301
27302         jobid_var_new=$($LCTL get_param -n $testname)
27303         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27304                 error "$testname was changed by setting without value"
27305 }
27306 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27307
27308 test_401d() {
27309         # jobid_var may not allow arbitrary values, so use jobid_name
27310         # if available
27311         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27312                 local testname=jobid_name new_value='foo=bar%p'
27313         else
27314                 local testname=jobid_var new_valuie=foo=bar
27315         fi
27316
27317         local jobid_var_old=$($LCTL get_param -n $testname)
27318         local jobid_var_new
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         # Reset the $testname to test the other format
27328         $LCTL set_param $testname=$jobid_var_old
27329         jobid_var_new=$($LCTL get_param -n $testname)
27330         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27331                 error "failed to reset $testname"
27332
27333         $LCTL set_param $testname $new_value ||
27334                 error "'set_param a b' did not accept a value containing '='"
27335
27336         jobid_var_new=$($LCTL get_param -n $testname)
27337         [[ "$jobid_var_new" == "$new_value" ]] ||
27338                 error "'set_param a b' failed on a value containing '='"
27339
27340         $LCTL set_param $testname $jobid_var_old
27341         jobid_var_new=$($LCTL get_param -n $testname)
27342         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27343                 error "failed to reset $testname"
27344 }
27345 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27346
27347 test_401e() { # LU-14779
27348         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27349                 error "lctl list_param MGC* failed"
27350         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27351         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27352                 error "lctl get_param lru_size failed"
27353 }
27354 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27355
27356 test_402() {
27357         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27358         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27359                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27360         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27361                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27362                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27363         remote_mds_nodsh && skip "remote MDS with nodsh"
27364
27365         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27366 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27367         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27368         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27369                 echo "Touch failed - OK"
27370 }
27371 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27372
27373 test_403() {
27374         local file1=$DIR/$tfile.1
27375         local file2=$DIR/$tfile.2
27376         local tfile=$TMP/$tfile
27377
27378         rm -f $file1 $file2 $tfile
27379
27380         touch $file1
27381         ln $file1 $file2
27382
27383         # 30 sec OBD_TIMEOUT in ll_getattr()
27384         # right before populating st_nlink
27385         $LCTL set_param fail_loc=0x80001409
27386         stat -c %h $file1 > $tfile &
27387
27388         # create an alias, drop all locks and reclaim the dentry
27389         < $file2
27390         cancel_lru_locks mdc
27391         cancel_lru_locks osc
27392         sysctl -w vm.drop_caches=2
27393
27394         wait
27395
27396         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27397
27398         rm -f $tfile $file1 $file2
27399 }
27400 run_test 403 "i_nlink should not drop to zero due to aliasing"
27401
27402 test_404() { # LU-6601
27403         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27404                 skip "Need server version newer than 2.8.52"
27405         remote_mds_nodsh && skip "remote MDS with nodsh"
27406
27407         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27408                 awk '/osp .*-osc-MDT/ { print $4}')
27409
27410         local osp
27411         for osp in $mosps; do
27412                 echo "Deactivate: " $osp
27413                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27414                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27415                         awk -vp=$osp '$4 == p { print $2 }')
27416                 [ $stat = IN ] || {
27417                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27418                         error "deactivate error"
27419                 }
27420                 echo "Activate: " $osp
27421                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27422                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27423                         awk -vp=$osp '$4 == p { print $2 }')
27424                 [ $stat = UP ] || {
27425                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27426                         error "activate error"
27427                 }
27428         done
27429 }
27430 run_test 404 "validate manual {de}activated works properly for OSPs"
27431
27432 test_405() {
27433         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27434         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27435                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27436                         skip "Layout swap lock is not supported"
27437
27438         check_swap_layouts_support
27439         check_swap_layout_no_dom $DIR
27440
27441         test_mkdir $DIR/$tdir
27442         swap_lock_test -d $DIR/$tdir ||
27443                 error "One layout swap locked test failed"
27444 }
27445 run_test 405 "Various layout swap lock tests"
27446
27447 test_406() {
27448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27449         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27450         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27452         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27453                 skip "Need MDS version at least 2.8.50"
27454
27455         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27456         local test_pool=$TESTNAME
27457
27458         pool_add $test_pool || error "pool_add failed"
27459         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27460                 error "pool_add_targets failed"
27461
27462         save_layout_restore_at_exit $MOUNT
27463
27464         # parent set default stripe count only, child will stripe from both
27465         # parent and fs default
27466         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27467                 error "setstripe $MOUNT failed"
27468         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27469         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27470         for i in $(seq 10); do
27471                 local f=$DIR/$tdir/$tfile.$i
27472                 touch $f || error "touch failed"
27473                 local count=$($LFS getstripe -c $f)
27474                 [ $count -eq $OSTCOUNT ] ||
27475                         error "$f stripe count $count != $OSTCOUNT"
27476                 local offset=$($LFS getstripe -i $f)
27477                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27478                 local size=$($LFS getstripe -S $f)
27479                 [ $size -eq $((def_stripe_size * 2)) ] ||
27480                         error "$f stripe size $size != $((def_stripe_size * 2))"
27481                 local pool=$($LFS getstripe -p $f)
27482                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27483         done
27484
27485         # change fs default striping, delete parent default striping, now child
27486         # will stripe from new fs default striping only
27487         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27488                 error "change $MOUNT default stripe failed"
27489         $LFS setstripe -c 0 $DIR/$tdir ||
27490                 error "delete $tdir default stripe failed"
27491         for i in $(seq 11 20); do
27492                 local f=$DIR/$tdir/$tfile.$i
27493                 touch $f || error "touch $f failed"
27494                 local count=$($LFS getstripe -c $f)
27495                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27496                 local offset=$($LFS getstripe -i $f)
27497                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27498                 local size=$($LFS getstripe -S $f)
27499                 [ $size -eq $def_stripe_size ] ||
27500                         error "$f stripe size $size != $def_stripe_size"
27501                 local pool=$($LFS getstripe -p $f)
27502                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27503         done
27504
27505         unlinkmany $DIR/$tdir/$tfile. 1 20
27506
27507         local f=$DIR/$tdir/$tfile
27508         pool_remove_all_targets $test_pool $f
27509         pool_remove $test_pool $f
27510 }
27511 run_test 406 "DNE support fs default striping"
27512
27513 test_407() {
27514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27515         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27516                 skip "Need MDS version at least 2.8.55"
27517         remote_mds_nodsh && skip "remote MDS with nodsh"
27518
27519         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27520                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27521         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27522                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27523         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27524
27525         #define OBD_FAIL_DT_TXN_STOP    0x2019
27526         for idx in $(seq $MDSCOUNT); do
27527                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27528         done
27529         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27530         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27531                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27532         true
27533 }
27534 run_test 407 "transaction fail should cause operation fail"
27535
27536 test_408() {
27537         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27538
27539         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27540         lctl set_param fail_loc=0x8000040a
27541         # let ll_prepare_partial_page() fail
27542         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27543
27544         rm -f $DIR/$tfile
27545
27546         # create at least 100 unused inodes so that
27547         # shrink_icache_memory(0) should not return 0
27548         touch $DIR/$tfile-{0..100}
27549         rm -f $DIR/$tfile-{0..100}
27550         sync
27551
27552         echo 2 > /proc/sys/vm/drop_caches
27553 }
27554 run_test 408 "drop_caches should not hang due to page leaks"
27555
27556 test_409()
27557 {
27558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27559
27560         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27561         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27562         touch $DIR/$tdir/guard || error "(2) Fail to create"
27563
27564         local PREFIX=$(str_repeat 'A' 128)
27565         echo "Create 1K hard links start at $(date)"
27566         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27567                 error "(3) Fail to hard link"
27568
27569         echo "Links count should be right although linkEA overflow"
27570         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27571         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27572         [ $linkcount -eq 1001 ] ||
27573                 error "(5) Unexpected hard links count: $linkcount"
27574
27575         echo "List all links start at $(date)"
27576         ls -l $DIR/$tdir/foo > /dev/null ||
27577                 error "(6) Fail to list $DIR/$tdir/foo"
27578
27579         echo "Unlink hard links start at $(date)"
27580         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27581                 error "(7) Fail to unlink"
27582         echo "Unlink hard links finished at $(date)"
27583 }
27584 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27585
27586 test_410()
27587 {
27588         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27589                 skip "Need client version at least 2.9.59"
27590         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27591                 skip "Need MODULES build"
27592
27593         # Create a file, and stat it from the kernel
27594         local testfile=$DIR/$tfile
27595         touch $testfile
27596
27597         local run_id=$RANDOM
27598         local my_ino=$(stat --format "%i" $testfile)
27599
27600         # Try to insert the module. This will always fail as the
27601         # module is designed to not be inserted.
27602         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27603             &> /dev/null
27604
27605         # Anything but success is a test failure
27606         dmesg | grep -q \
27607             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27608             error "no inode match"
27609 }
27610 run_test 410 "Test inode number returned from kernel thread"
27611
27612 cleanup_test411_cgroup() {
27613         trap 0
27614         cat $1/memory.stat
27615         rmdir "$1"
27616 }
27617
27618 test_411a() {
27619         local cg_basedir=/sys/fs/cgroup/memory
27620         # LU-9966
27621         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27622                 skip "no setup for cgroup"
27623
27624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27625                 error "test file creation failed"
27626         cancel_lru_locks osc
27627
27628         # Create a very small memory cgroup to force a slab allocation error
27629         local cgdir=$cg_basedir/osc_slab_alloc
27630         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27631         trap "cleanup_test411_cgroup $cgdir" EXIT
27632         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27633         echo 1M > $cgdir/memory.limit_in_bytes
27634
27635         # Should not LBUG, just be killed by oom-killer
27636         # dd will return 0 even allocation failure in some environment.
27637         # So don't check return value
27638         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27639         cleanup_test411_cgroup $cgdir
27640
27641         return 0
27642 }
27643 run_test 411a "Slab allocation error with cgroup does not LBUG"
27644
27645 test_411b() {
27646         local cg_basedir=/sys/fs/cgroup/memory
27647         # LU-9966
27648         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27649                 skip "no setup for cgroup"
27650         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27651         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27652         # limit, so we have 384M in cgroup
27653         # (arm) this seems to hit OOM more often than x86, so 1024M
27654         if [[ $(uname -m) = aarch64 ]]; then
27655                 local memlimit_mb=1024
27656         else
27657                 local memlimit_mb=384
27658         fi
27659
27660         # Create a cgroup and set memory limit
27661         # (tfile is used as an easy way to get a recognizable cgroup name)
27662         local cgdir=$cg_basedir/$tfile
27663         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27664         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27665         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27666
27667         echo "writing first file"
27668         # Write a file 4x the memory limit in size
27669         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27670                 error "(1) failed to write successfully"
27671
27672         sync
27673         cancel_lru_locks osc
27674
27675         rm -f $DIR/$tfile
27676         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27677
27678         # Try writing at a larger block size
27679         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27680         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27681         # need *some* memory to do IO in)
27682         echo "writing at larger block size"
27683         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27684                 error "(3) failed to write successfully"
27685
27686         sync
27687         cancel_lru_locks osc
27688         rm -f $DIR/$tfile
27689         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27690
27691         # Try writing multiple files at once
27692         echo "writing multiple files"
27693         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27694         local pid1=$!
27695         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27696         local pid2=$!
27697         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27698         local pid3=$!
27699         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27700         local pid4=$!
27701
27702         wait $pid1
27703         local rc1=$?
27704         wait $pid2
27705         local rc2=$?
27706         wait $pid3
27707         local rc3=$?
27708         wait $pid4
27709         local rc4=$?
27710         if (( rc1 != 0)); then
27711                 error "error $rc1 writing to file from $pid1"
27712         fi
27713         if (( rc2 != 0)); then
27714                 error "error $rc2 writing to file from $pid2"
27715         fi
27716         if (( rc3 != 0)); then
27717                 error "error $rc3 writing to file from $pid3"
27718         fi
27719         if (( rc4 != 0)); then
27720                 error "error $rc4 writing to file from $pid4"
27721         fi
27722
27723         sync
27724         cancel_lru_locks osc
27725
27726         # These files can be large-ish (~1 GiB total), so delete them rather
27727         # than leave for later cleanup
27728         rm -f $DIR/$tfile.*
27729         return 0
27730 }
27731 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27732
27733 test_412() {
27734         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27735         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27736                 skip "Need server version at least 2.10.55"
27737
27738         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27739                 error "mkdir failed"
27740         $LFS getdirstripe $DIR/$tdir
27741         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27742         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27743                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27744         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27745         [ $stripe_count -eq 2 ] ||
27746                 error "expect 2 get $stripe_count"
27747
27748         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27749
27750         local index
27751         local index2
27752
27753         # subdirs should be on the same MDT as parent
27754         for i in $(seq 0 $((MDSCOUNT - 1))); do
27755                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27756                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27757                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27758                 (( index == i )) || error "mdt$i/sub on MDT$index"
27759         done
27760
27761         # stripe offset -1, ditto
27762         for i in {1..10}; do
27763                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27764                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27765                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27766                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27767                 (( index == index2 )) ||
27768                         error "qos$i on MDT$index, sub on MDT$index2"
27769         done
27770
27771         local testdir=$DIR/$tdir/inherit
27772
27773         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27774         # inherit 2 levels
27775         for i in 1 2; do
27776                 testdir=$testdir/s$i
27777                 mkdir $testdir || error "mkdir $testdir failed"
27778                 index=$($LFS getstripe -m $testdir)
27779                 (( index == 1 )) ||
27780                         error "$testdir on MDT$index"
27781         done
27782
27783         # not inherit any more
27784         testdir=$testdir/s3
27785         mkdir $testdir || error "mkdir $testdir failed"
27786         getfattr -d -m dmv $testdir | grep dmv &&
27787                 error "default LMV set on $testdir" || true
27788 }
27789 run_test 412 "mkdir on specific MDTs"
27790
27791 TEST413_COUNT=${TEST413_COUNT:-200}
27792
27793 #
27794 # set_maxage() is used by test_413 only.
27795 # This is a helper function to set maxage. Does not return any value.
27796 # Input: maxage to set
27797 #
27798 set_maxage() {
27799         local lmv_qos_maxage
27800         local lod_qos_maxage
27801         local new_maxage=$1
27802
27803         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27804         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27805         stack_trap "$LCTL set_param \
27806                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27807         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27808                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27809         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27810                 lod.*.mdt_qos_maxage=$new_maxage
27811         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27812                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27813 }
27814
27815 generate_uneven_mdts() {
27816         local threshold=$1
27817         local ffree
27818         local bavail
27819         local max
27820         local min
27821         local max_index
27822         local min_index
27823         local tmp
27824         local i
27825
27826         echo
27827         echo "Check for uneven MDTs: "
27828
27829         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27830         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27831         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27832
27833         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27834         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27835         max_index=0
27836         min_index=0
27837         for ((i = 1; i < ${#ffree[@]}; i++)); do
27838                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27839                 if [ $tmp -gt $max ]; then
27840                         max=$tmp
27841                         max_index=$i
27842                 fi
27843                 if [ $tmp -lt $min ]; then
27844                         min=$tmp
27845                         min_index=$i
27846                 fi
27847         done
27848
27849         (( min > 0 )) || skip "low space on MDT$min_index"
27850         (( ${ffree[min_index]} > 0 )) ||
27851                 skip "no free files on MDT$min_index"
27852         (( ${ffree[min_index]} < 10000000 )) ||
27853                 skip "too many free files on MDT$min_index"
27854
27855         # Check if we need to generate uneven MDTs
27856         local diff=$(((max - min) * 100 / min))
27857         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27858         local testdir # individual folder within $testdirp
27859         local start
27860         local cmd
27861
27862         # fallocate is faster to consume space on MDT, if available
27863         if check_fallocate_supported mds$((min_index + 1)); then
27864                 cmd="fallocate -l 128K "
27865         else
27866                 cmd="dd if=/dev/zero bs=128K count=1 of="
27867         fi
27868
27869         echo "using cmd $cmd"
27870         for (( i = 0; diff < threshold; i++ )); do
27871                 testdir=${testdirp}/$i
27872                 [ -d $testdir ] && continue
27873
27874                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27875
27876                 mkdir -p $testdirp
27877                 # generate uneven MDTs, create till $threshold% diff
27878                 echo -n "weight diff=$diff% must be > $threshold% ..."
27879                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27880                 $LFS mkdir -i $min_index $testdir ||
27881                         error "mkdir $testdir failed"
27882                 $LFS setstripe -E 1M -L mdt $testdir ||
27883                         error "setstripe $testdir failed"
27884                 start=$SECONDS
27885                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27886                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27887                 done
27888                 sync; sleep 1; sync
27889
27890                 # wait for QOS to update
27891                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27892
27893                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27894                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27895                 max=$(((${ffree[max_index]} >> 8) *
27896                         (${bavail[max_index]} * bsize >> 16)))
27897                 min=$(((${ffree[min_index]} >> 8) *
27898                         (${bavail[min_index]} * bsize >> 16)))
27899                 (( min > 0 )) || skip "low space on MDT$min_index"
27900                 diff=$(((max - min) * 100 / min))
27901         done
27902
27903         echo "MDT filesfree available: ${ffree[*]}"
27904         echo "MDT blocks available: ${bavail[*]}"
27905         echo "weight diff=$diff%"
27906 }
27907
27908 test_qos_mkdir() {
27909         local mkdir_cmd=$1
27910         local stripe_count=$2
27911         local mdts=$(comma_list $(mdts_nodes))
27912
27913         local testdir
27914         local lmv_qos_prio_free
27915         local lmv_qos_threshold_rr
27916         local lod_qos_prio_free
27917         local lod_qos_threshold_rr
27918         local total
27919         local count
27920         local i
27921
27922         # @total is total directories created if it's testing plain
27923         # directories, otherwise it's total stripe object count for
27924         # striped directories test.
27925         # remote/striped directory unlinking is slow on zfs and may
27926         # timeout, test with fewer directories
27927         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27928
27929         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27930         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27931         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27932                 head -n1)
27933         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27934         stack_trap "$LCTL set_param \
27935                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27936         stack_trap "$LCTL set_param \
27937                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27938
27939         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27940                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27941         lod_qos_prio_free=${lod_qos_prio_free%%%}
27942         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27943                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27944         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27945         stack_trap "do_nodes $mdts $LCTL set_param \
27946                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27947         stack_trap "do_nodes $mdts $LCTL set_param \
27948                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27949
27950         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27951         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27952
27953         testdir=$DIR/$tdir-s$stripe_count/rr
27954
27955         local stripe_index=$($LFS getstripe -m $testdir)
27956         local test_mkdir_rr=true
27957
27958         getfattr -d -m dmv -e hex $testdir | grep dmv
27959         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27960                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27961                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27962                         test_mkdir_rr=false
27963         fi
27964
27965         echo
27966         $test_mkdir_rr &&
27967                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27968                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27969
27970         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27971         for (( i = 0; i < total / stripe_count; i++ )); do
27972                 eval $mkdir_cmd $testdir/subdir$i ||
27973                         error "$mkdir_cmd subdir$i failed"
27974         done
27975
27976         for (( i = 0; i < $MDSCOUNT; i++ )); do
27977                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27978                 echo "$count directories created on MDT$i"
27979                 if $test_mkdir_rr; then
27980                         (( count == total / stripe_count / MDSCOUNT )) ||
27981                                 error "subdirs are not evenly distributed"
27982                 elif (( i == stripe_index )); then
27983                         (( count == total / stripe_count )) ||
27984                                 error "$count subdirs created on MDT$i"
27985                 else
27986                         (( count == 0 )) ||
27987                                 error "$count subdirs created on MDT$i"
27988                 fi
27989
27990                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27991                         count=$($LFS getdirstripe $testdir/* |
27992                                 grep -c -P "^\s+$i\t")
27993                         echo "$count stripes created on MDT$i"
27994                         # deviation should < 5% of average
27995                         delta=$((count - total / MDSCOUNT))
27996                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27997                                 error "stripes are not evenly distributed"
27998                 fi
27999         done
28000
28001         echo
28002         echo "Check for uneven MDTs: "
28003
28004         local ffree
28005         local bavail
28006         local max
28007         local min
28008         local max_index
28009         local min_index
28010         local tmp
28011
28012         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28013         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28014         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28015
28016         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28017         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28018         max_index=0
28019         min_index=0
28020         for ((i = 1; i < ${#ffree[@]}; i++)); do
28021                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28022                 if [ $tmp -gt $max ]; then
28023                         max=$tmp
28024                         max_index=$i
28025                 fi
28026                 if [ $tmp -lt $min ]; then
28027                         min=$tmp
28028                         min_index=$i
28029                 fi
28030         done
28031         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28032
28033         (( min > 0 )) || skip "low space on MDT$min_index"
28034         (( ${ffree[min_index]} < 10000000 )) ||
28035                 skip "too many free files on MDT$min_index"
28036
28037         generate_uneven_mdts 120
28038
28039         echo "MDT filesfree available: ${ffree[*]}"
28040         echo "MDT blocks available: ${bavail[*]}"
28041         echo "weight diff=$(((max - min) * 100 / min))%"
28042         echo
28043         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28044
28045         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28046         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28047         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28048         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28049         # decrease statfs age, so that it can be updated in time
28050         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28051         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28052
28053         sleep 1
28054
28055         testdir=$DIR/$tdir-s$stripe_count/qos
28056
28057         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28058         for (( i = 0; i < total / stripe_count; i++ )); do
28059                 eval $mkdir_cmd $testdir/subdir$i ||
28060                         error "$mkdir_cmd subdir$i failed"
28061         done
28062
28063         max=0
28064         for (( i = 0; i < $MDSCOUNT; i++ )); do
28065                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28066                 (( count > max )) && max=$count
28067                 echo "$count directories created on MDT$i : curmax=$max"
28068         done
28069
28070         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28071
28072         # D-value should > 10% of average
28073         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28074                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28075
28076         # ditto for stripes
28077         if (( stripe_count > 1 )); then
28078                 max=0
28079                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28080                         count=$($LFS getdirstripe $testdir/* |
28081                                 grep -c -P "^\s+$i\t")
28082                         (( count > max )) && max=$count
28083                         echo "$count stripes created on MDT$i"
28084                 done
28085
28086                 min=$($LFS getdirstripe $testdir/* |
28087                         grep -c -P "^\s+$min_index\t")
28088                 (( max - min > total / MDSCOUNT / 10 )) ||
28089                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28090         fi
28091 }
28092
28093 most_full_mdt() {
28094         local ffree
28095         local bavail
28096         local bsize
28097         local min
28098         local min_index
28099         local tmp
28100
28101         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28102         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28103         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28104
28105         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28106         min_index=0
28107         for ((i = 1; i < ${#ffree[@]}; i++)); do
28108                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28109                 (( tmp < min )) && min=$tmp && min_index=$i
28110         done
28111
28112         echo -n $min_index
28113 }
28114
28115 test_413a() {
28116         [ $MDSCOUNT -lt 2 ] &&
28117                 skip "We need at least 2 MDTs for this test"
28118
28119         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28120                 skip "Need server version at least 2.12.52"
28121
28122         local stripe_max=$((MDSCOUNT - 1))
28123         local stripe_count
28124
28125         # let caller set maxage for latest result
28126         set_maxage 1
28127
28128         # fill MDT unevenly
28129         generate_uneven_mdts 120
28130
28131         # test 4-stripe directory at most, otherwise it's too slow
28132         # We are being very defensive. Although Autotest uses 4 MDTs.
28133         # We make sure stripe_max does not go over 4.
28134         (( stripe_max > 4 )) && stripe_max=4
28135         # unlinking striped directory is slow on zfs, and may timeout, only test
28136         # plain directory
28137         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28138         for stripe_count in $(seq 1 $stripe_max); do
28139                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28140                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28141                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28142                         error "mkdir failed"
28143                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28144         done
28145 }
28146 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28147
28148 test_413b() {
28149         [ $MDSCOUNT -lt 2 ] &&
28150                 skip "We need at least 2 MDTs for this test"
28151
28152         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28153                 skip "Need server version at least 2.12.52"
28154
28155         local stripe_max=$((MDSCOUNT - 1))
28156         local testdir
28157         local stripe_count
28158
28159         # let caller set maxage for latest result
28160         set_maxage 1
28161
28162         # fill MDT unevenly
28163         generate_uneven_mdts 120
28164
28165         # test 4-stripe directory at most, otherwise it's too slow
28166         # We are being very defensive. Although Autotest uses 4 MDTs.
28167         # We make sure stripe_max does not go over 4.
28168         (( stripe_max > 4 )) && stripe_max=4
28169         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28170         for stripe_count in $(seq 1 $stripe_max); do
28171                 testdir=$DIR/$tdir-s$stripe_count
28172                 mkdir $testdir || error "mkdir $testdir failed"
28173                 mkdir $testdir/rr || error "mkdir rr failed"
28174                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28175                         error "mkdir qos failed"
28176                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28177                         $testdir/rr || error "setdirstripe rr failed"
28178                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28179                         error "setdirstripe failed"
28180                 test_qos_mkdir "mkdir" $stripe_count
28181         done
28182 }
28183 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28184
28185 test_413c() {
28186         (( $MDSCOUNT >= 2 )) ||
28187                 skip "We need at least 2 MDTs for this test"
28188
28189         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28190                 skip "Need server version at least 2.14.51"
28191
28192         local testdir
28193         local inherit
28194         local inherit_rr
28195         local lmv_qos_maxage
28196         local lod_qos_maxage
28197
28198         # let caller set maxage for latest result
28199         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28200         $LCTL set_param lmv.*.qos_maxage=1
28201         stack_trap "$LCTL set_param \
28202                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28203         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28204                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28205         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28206                 lod.*.mdt_qos_maxage=1
28207         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28208                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28209
28210         # fill MDT unevenly
28211         generate_uneven_mdts 120
28212
28213         testdir=$DIR/${tdir}-s1
28214         mkdir $testdir || error "mkdir $testdir failed"
28215         mkdir $testdir/rr || error "mkdir rr failed"
28216         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28217         # default max_inherit is -1, default max_inherit_rr is 0
28218         $LFS setdirstripe -D -c 1 $testdir/rr ||
28219                 error "setdirstripe rr failed"
28220         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28221                 error "setdirstripe qos failed"
28222         test_qos_mkdir "mkdir" 1
28223
28224         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28225         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28226         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28227         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28228         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28229
28230         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28231         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28232         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28233         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28234         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28235         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28236         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28237                 error "level2 shouldn't have default LMV" || true
28238 }
28239 run_test 413c "mkdir with default LMV max inherit rr"
28240
28241 test_413d() {
28242         (( MDSCOUNT >= 2 )) ||
28243                 skip "We need at least 2 MDTs for this test"
28244
28245         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28246                 skip "Need server version at least 2.14.51"
28247
28248         local lmv_qos_threshold_rr
28249
28250         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28251                 head -n1)
28252         stack_trap "$LCTL set_param \
28253                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28254
28255         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28256         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28257         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28258                 error "$tdir shouldn't have default LMV"
28259         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28260                 error "mkdir sub failed"
28261
28262         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28263
28264         (( count == 100 )) || error "$count subdirs on MDT0"
28265 }
28266 run_test 413d "inherit ROOT default LMV"
28267
28268 test_413e() {
28269         (( MDSCOUNT >= 2 )) ||
28270                 skip "We need at least 2 MDTs for this test"
28271         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28272                 skip "Need server version at least 2.14.55"
28273
28274         local testdir=$DIR/$tdir
28275         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28276         local max_inherit
28277         local sub_max_inherit
28278
28279         mkdir -p $testdir || error "failed to create $testdir"
28280
28281         # set default max-inherit to -1 if stripe count is 0 or 1
28282         $LFS setdirstripe -D -c 1 $testdir ||
28283                 error "failed to set default LMV"
28284         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28285         (( max_inherit == -1 )) ||
28286                 error "wrong max_inherit value $max_inherit"
28287
28288         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28289         $LFS setdirstripe -D -c -1 $testdir ||
28290                 error "failed to set default LMV"
28291         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28292         (( max_inherit > 0 )) ||
28293                 error "wrong max_inherit value $max_inherit"
28294
28295         # and the subdir will decrease the max_inherit by 1
28296         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28297         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28298         (( sub_max_inherit == max_inherit - 1)) ||
28299                 error "wrong max-inherit of subdir $sub_max_inherit"
28300
28301         # check specified --max-inherit and warning message
28302         stack_trap "rm -f $tmpfile"
28303         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28304                 error "failed to set default LMV"
28305         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28306         (( max_inherit == -1 )) ||
28307                 error "wrong max_inherit value $max_inherit"
28308
28309         # check the warning messages
28310         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28311                 error "failed to detect warning string"
28312         fi
28313 }
28314 run_test 413e "check default max-inherit value"
28315
28316 test_fs_dmv_inherit()
28317 {
28318         local testdir=$DIR/$tdir
28319
28320         local count
28321         local inherit
28322         local inherit_rr
28323
28324         for i in 1 2; do
28325                 mkdir $testdir || error "mkdir $testdir failed"
28326                 count=$($LFS getdirstripe -D -c $testdir)
28327                 (( count == 1 )) ||
28328                         error "$testdir default LMV count mismatch $count != 1"
28329                 inherit=$($LFS getdirstripe -D -X $testdir)
28330                 (( inherit == 3 - i )) ||
28331                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28332                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28333                 (( inherit_rr == 3 - i )) ||
28334                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28335                 testdir=$testdir/sub
28336         done
28337
28338         mkdir $testdir || error "mkdir $testdir failed"
28339         count=$($LFS getdirstripe -D -c $testdir)
28340         (( count == 0 )) ||
28341                 error "$testdir default LMV count not zero: $count"
28342 }
28343
28344 test_413f() {
28345         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28346
28347         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28348                 skip "Need server version at least 2.14.55"
28349
28350         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28351                 error "dump $DIR default LMV failed"
28352         stack_trap "setfattr --restore=$TMP/dmv.ea"
28353
28354         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28355                 error "set $DIR default LMV failed"
28356
28357         test_fs_dmv_inherit
28358 }
28359 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28360
28361 test_413g() {
28362         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28363
28364         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28365         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28366                 error "dump $DIR default LMV failed"
28367         stack_trap "setfattr --restore=$TMP/dmv.ea"
28368
28369         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28370                 error "set $DIR default LMV failed"
28371
28372         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28373                 error "mount $MOUNT2 failed"
28374         stack_trap "umount_client $MOUNT2"
28375
28376         local saved_DIR=$DIR
28377
28378         export DIR=$MOUNT2
28379
28380         stack_trap "export DIR=$saved_DIR"
28381
28382         # first check filesystem-wide default LMV inheritance
28383         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28384
28385         # then check subdirs are spread to all MDTs
28386         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28387
28388         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28389
28390         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28391 }
28392 run_test 413g "enforce ROOT default LMV on subdir mount"
28393
28394 test_413h() {
28395         (( MDSCOUNT >= 2 )) ||
28396                 skip "We need at least 2 MDTs for this test"
28397
28398         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28399                 skip "Need server version at least 2.15.50.6"
28400
28401         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28402
28403         stack_trap "$LCTL set_param \
28404                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28405         $LCTL set_param lmv.*.qos_maxage=1
28406
28407         local depth=5
28408         local rr_depth=4
28409         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28410         local count=$((MDSCOUNT * 20))
28411
28412         generate_uneven_mdts 50
28413
28414         mkdir -p $dir || error "mkdir $dir failed"
28415         stack_trap "rm -rf $dir"
28416         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28417                 --max-inherit-rr=$rr_depth $dir
28418
28419         for ((d=0; d < depth + 2; d++)); do
28420                 log "dir=$dir:"
28421                 for ((sub=0; sub < count; sub++)); do
28422                         mkdir $dir/d$sub
28423                 done
28424                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28425                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28426                 # subdirs within $rr_depth should be created round-robin
28427                 if (( d < rr_depth )); then
28428                         (( ${num[0]} != count )) ||
28429                                 error "all objects created on MDT ${num[1]}"
28430                 fi
28431
28432                 dir=$dir/d0
28433         done
28434 }
28435 run_test 413h "don't stick to parent for round-robin dirs"
28436
28437 test_413i() {
28438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28439
28440         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28441                 skip "Need server version at least 2.14.55"
28442
28443         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28444                 error "dump $DIR default LMV failed"
28445         stack_trap "setfattr --restore=$TMP/dmv.ea"
28446
28447         local testdir=$DIR/$tdir
28448         local def_max_rr=1
28449         local def_max=3
28450         local count
28451
28452         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28453                 --max-inherit-rr=$def_max_rr $DIR ||
28454                 error "set $DIR default LMV failed"
28455
28456         for i in $(seq 2 3); do
28457                 def_max=$((def_max - 1))
28458                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28459
28460                 mkdir $testdir
28461                 # RR is decremented and keeps zeroed once exhausted
28462                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28463                 (( count == def_max_rr )) ||
28464                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28465
28466                 # max-inherit is decremented
28467                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28468                 (( count == def_max )) ||
28469                         error_noexit "$testdir: max-inherit $count != $def_max"
28470
28471                 testdir=$testdir/d$i
28472         done
28473
28474         # d3 is the last inherited from ROOT, no inheritance anymore
28475         # i.e. no the default layout anymore
28476         mkdir -p $testdir/d4/d5
28477         count=$($LFS getdirstripe -D --max-inherit $testdir)
28478         (( count == -1 )) ||
28479                 error_noexit "$testdir: max-inherit $count != -1"
28480
28481         local p_count=$($LFS getdirstripe -i $testdir)
28482
28483         for i in $(seq 4 5); do
28484                 testdir=$testdir/d$i
28485
28486                 # the root default layout is not applied once exhausted
28487                 count=$($LFS getdirstripe -i $testdir)
28488                 (( count == p_count )) ||
28489                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28490         done
28491
28492         $LFS setdirstripe -i 0 $DIR/d2
28493         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28494         (( count == -1 )) ||
28495                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28496 }
28497 run_test 413i "check default layout inheritance"
28498
28499 test_413z() {
28500         local pids=""
28501         local subdir
28502         local pid
28503
28504         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28505                 unlinkmany $subdir/f. $TEST413_COUNT &
28506                 pids="$pids $!"
28507         done
28508
28509         for pid in $pids; do
28510                 wait $pid
28511         done
28512
28513         true
28514 }
28515 run_test 413z "413 test cleanup"
28516
28517 test_414() {
28518 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28519         $LCTL set_param fail_loc=0x80000521
28520         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28521         rm -f $DIR/$tfile
28522 }
28523 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28524
28525 test_415() {
28526         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28527         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28528                 skip "Need server version at least 2.11.52"
28529
28530         # LU-11102
28531         local total=500
28532         local max=120
28533
28534         # this test may be slow on ZFS
28535         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28536
28537         # though this test is designed for striped directory, let's test normal
28538         # directory too since lock is always saved as CoS lock.
28539         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28540         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28541         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28542         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28543         wait_delete_completed_mds
28544
28545         # run a loop without concurrent touch to measure rename duration.
28546         # only for test debug/robustness, NOT part of COS functional test.
28547         local start_time=$SECONDS
28548         for ((i = 0; i < total; i++)); do
28549                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28550                         > /dev/null
28551         done
28552         local baseline=$((SECONDS - start_time))
28553         echo "rename $total files without 'touch' took $baseline sec"
28554
28555         (
28556                 while true; do
28557                         touch $DIR/$tdir
28558                 done
28559         ) &
28560         local setattr_pid=$!
28561
28562         # rename files back to original name so unlinkmany works
28563         start_time=$SECONDS
28564         for ((i = 0; i < total; i++)); do
28565                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28566                         > /dev/null
28567         done
28568         local duration=$((SECONDS - start_time))
28569
28570         kill -9 $setattr_pid
28571
28572         echo "rename $total files with 'touch' took $duration sec"
28573         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28574         (( duration <= max )) ||
28575                 error_not_in_vm "rename took $duration > $max sec"
28576 }
28577 run_test 415 "lock revoke is not missing"
28578
28579 test_416() {
28580         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28581                 skip "Need server version at least 2.11.55"
28582
28583         # define OBD_FAIL_OSD_TXN_START    0x19a
28584         do_facet mds1 lctl set_param fail_loc=0x19a
28585
28586         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28587
28588         true
28589 }
28590 run_test 416 "transaction start failure won't cause system hung"
28591
28592 cleanup_417() {
28593         trap 0
28594         do_nodes $(comma_list $(mdts_nodes)) \
28595                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28596         do_nodes $(comma_list $(mdts_nodes)) \
28597                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28598         do_nodes $(comma_list $(mdts_nodes)) \
28599                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28600 }
28601
28602 test_417() {
28603         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28604         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28605                 skip "Need MDS version at least 2.11.56"
28606
28607         trap cleanup_417 RETURN EXIT
28608
28609         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28610         do_nodes $(comma_list $(mdts_nodes)) \
28611                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28612         $LFS migrate -m 0 $DIR/$tdir.1 &&
28613                 error "migrate dir $tdir.1 should fail"
28614
28615         do_nodes $(comma_list $(mdts_nodes)) \
28616                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28617         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28618                 error "create remote dir $tdir.2 should fail"
28619
28620         do_nodes $(comma_list $(mdts_nodes)) \
28621                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28622         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28623                 error "create striped dir $tdir.3 should fail"
28624         true
28625 }
28626 run_test 417 "disable remote dir, striped dir and dir migration"
28627
28628 # Checks that the outputs of df [-i] and lfs df [-i] match
28629 #
28630 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28631 check_lfs_df() {
28632         local dir=$2
28633         local inodes
28634         local df_out
28635         local lfs_df_out
28636         local count
28637         local passed=false
28638
28639         # blocks or inodes
28640         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28641
28642         for count in {1..100}; do
28643                 do_nodes "$CLIENTS" \
28644                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28645                 sync; sleep 0.2
28646
28647                 # read the lines of interest
28648                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28649                         error "df $inodes $dir | tail -n +2 failed"
28650                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28651                         error "lfs df $inodes $dir | grep summary: failed"
28652
28653                 # skip first substrings of each output as they are different
28654                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28655                 # compare the two outputs
28656                 passed=true
28657                 #  skip "available" on MDT until LU-13997 is fixed.
28658                 #for i in {1..5}; do
28659                 for i in 1 2 4 5; do
28660                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28661                 done
28662                 $passed && break
28663         done
28664
28665         if ! $passed; then
28666                 df -P $inodes $dir
28667                 echo
28668                 lfs df $inodes $dir
28669                 error "df and lfs df $1 output mismatch: "      \
28670                       "df ${inodes}: ${df_out[*]}, "            \
28671                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28672         fi
28673 }
28674
28675 test_418() {
28676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28677
28678         local dir=$DIR/$tdir
28679         local numfiles=$((RANDOM % 4096 + 2))
28680         local numblocks=$((RANDOM % 256 + 1))
28681
28682         wait_delete_completed
28683         test_mkdir $dir
28684
28685         # check block output
28686         check_lfs_df blocks $dir
28687         # check inode output
28688         check_lfs_df inodes $dir
28689
28690         # create a single file and retest
28691         echo "Creating a single file and testing"
28692         createmany -o $dir/$tfile- 1 &>/dev/null ||
28693                 error "creating 1 file in $dir failed"
28694         check_lfs_df blocks $dir
28695         check_lfs_df inodes $dir
28696
28697         # create a random number of files
28698         echo "Creating $((numfiles - 1)) files and testing"
28699         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28700                 error "creating $((numfiles - 1)) files in $dir failed"
28701
28702         # write a random number of blocks to the first test file
28703         echo "Writing $numblocks 4K blocks and testing"
28704         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28705                 count=$numblocks &>/dev/null ||
28706                 error "dd to $dir/${tfile}-0 failed"
28707
28708         # retest
28709         check_lfs_df blocks $dir
28710         check_lfs_df inodes $dir
28711
28712         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28713                 error "unlinking $numfiles files in $dir failed"
28714 }
28715 run_test 418 "df and lfs df outputs match"
28716
28717 test_419()
28718 {
28719         local dir=$DIR/$tdir
28720
28721         mkdir -p $dir
28722         touch $dir/file
28723
28724         cancel_lru_locks mdc
28725
28726         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28727         $LCTL set_param fail_loc=0x1410
28728         cat $dir/file
28729         $LCTL set_param fail_loc=0
28730         rm -rf $dir
28731 }
28732 run_test 419 "Verify open file by name doesn't crash kernel"
28733
28734 test_420()
28735 {
28736         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28737                 skip "Need MDS version at least 2.12.53"
28738
28739         local SAVE_UMASK=$(umask)
28740         local dir=$DIR/$tdir
28741         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28742
28743         mkdir -p $dir
28744         umask 0000
28745         mkdir -m03777 $dir/testdir
28746         ls -dn $dir/testdir
28747         # Need to remove trailing '.' when SELinux is enabled
28748         local dirperms=$(ls -dn $dir/testdir |
28749                          awk '{ sub(/\.$/, "", $1); print $1}')
28750         [ $dirperms == "drwxrwsrwt" ] ||
28751                 error "incorrect perms on $dir/testdir"
28752
28753         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28754                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28755         ls -n $dir/testdir/testfile
28756         local fileperms=$(ls -n $dir/testdir/testfile |
28757                           awk '{ sub(/\.$/, "", $1); print $1}')
28758         [ $fileperms == "-rwxr-xr-x" ] ||
28759                 error "incorrect perms on $dir/testdir/testfile"
28760
28761         umask $SAVE_UMASK
28762 }
28763 run_test 420 "clear SGID bit on non-directories for non-members"
28764
28765 test_421a() {
28766         local cnt
28767         local fid1
28768         local fid2
28769
28770         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28771                 skip "Need MDS version at least 2.12.54"
28772
28773         test_mkdir $DIR/$tdir
28774         createmany -o $DIR/$tdir/f 3
28775         cnt=$(ls -1 $DIR/$tdir | wc -l)
28776         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28777
28778         fid1=$(lfs path2fid $DIR/$tdir/f1)
28779         fid2=$(lfs path2fid $DIR/$tdir/f2)
28780         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28781
28782         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28783         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28784
28785         cnt=$(ls -1 $DIR/$tdir | wc -l)
28786         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28787
28788         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28789         createmany -o $DIR/$tdir/f 3
28790         cnt=$(ls -1 $DIR/$tdir | wc -l)
28791         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28792
28793         fid1=$(lfs path2fid $DIR/$tdir/f1)
28794         fid2=$(lfs path2fid $DIR/$tdir/f2)
28795         echo "remove using fsname $FSNAME"
28796         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28797
28798         cnt=$(ls -1 $DIR/$tdir | wc -l)
28799         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28800 }
28801 run_test 421a "simple rm by fid"
28802
28803 test_421b() {
28804         local cnt
28805         local FID1
28806         local FID2
28807
28808         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28809                 skip "Need MDS version at least 2.12.54"
28810
28811         test_mkdir $DIR/$tdir
28812         createmany -o $DIR/$tdir/f 3
28813         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28814         MULTIPID=$!
28815
28816         FID1=$(lfs path2fid $DIR/$tdir/f1)
28817         FID2=$(lfs path2fid $DIR/$tdir/f2)
28818         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28819
28820         kill -USR1 $MULTIPID
28821         wait
28822
28823         cnt=$(ls $DIR/$tdir | wc -l)
28824         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28825 }
28826 run_test 421b "rm by fid on open file"
28827
28828 test_421c() {
28829         local cnt
28830         local FIDS
28831
28832         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28833                 skip "Need MDS version at least 2.12.54"
28834
28835         test_mkdir $DIR/$tdir
28836         createmany -o $DIR/$tdir/f 3
28837         touch $DIR/$tdir/$tfile
28838         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28839         cnt=$(ls -1 $DIR/$tdir | wc -l)
28840         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28841
28842         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28843         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28844
28845         cnt=$(ls $DIR/$tdir | wc -l)
28846         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28847 }
28848 run_test 421c "rm by fid against hardlinked files"
28849
28850 test_421d() {
28851         local cnt
28852         local FIDS
28853
28854         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28855                 skip "Need MDS version at least 2.12.54"
28856
28857         test_mkdir $DIR/$tdir
28858         createmany -o $DIR/$tdir/f 4097
28859         cnt=$(ls -1 $DIR/$tdir | wc -l)
28860         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28861
28862         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28863         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28864
28865         cnt=$(ls $DIR/$tdir | wc -l)
28866         rm -rf $DIR/$tdir
28867         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28868 }
28869 run_test 421d "rmfid en masse"
28870
28871 test_421e() {
28872         local cnt
28873         local FID
28874
28875         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28876         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28877                 skip "Need MDS version at least 2.12.54"
28878
28879         mkdir -p $DIR/$tdir
28880         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28881         createmany -o $DIR/$tdir/striped_dir/f 512
28882         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28883         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28884
28885         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28886                 sed "s/[/][^:]*://g")
28887         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28888
28889         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28890         rm -rf $DIR/$tdir
28891         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28892 }
28893 run_test 421e "rmfid in DNE"
28894
28895 test_421f() {
28896         local cnt
28897         local FID
28898
28899         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28900                 skip "Need MDS version at least 2.12.54"
28901
28902         test_mkdir $DIR/$tdir
28903         touch $DIR/$tdir/f
28904         cnt=$(ls -1 $DIR/$tdir | wc -l)
28905         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28906
28907         FID=$(lfs path2fid $DIR/$tdir/f)
28908         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28909         # rmfid should fail
28910         cnt=$(ls -1 $DIR/$tdir | wc -l)
28911         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28912
28913         chmod a+rw $DIR/$tdir
28914         ls -la $DIR/$tdir
28915         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28916         # rmfid should fail
28917         cnt=$(ls -1 $DIR/$tdir | wc -l)
28918         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28919
28920         rm -f $DIR/$tdir/f
28921         $RUNAS touch $DIR/$tdir/f
28922         FID=$(lfs path2fid $DIR/$tdir/f)
28923         echo "rmfid as root"
28924         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28925         cnt=$(ls -1 $DIR/$tdir | wc -l)
28926         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28927
28928         rm -f $DIR/$tdir/f
28929         $RUNAS touch $DIR/$tdir/f
28930         cnt=$(ls -1 $DIR/$tdir | wc -l)
28931         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28932         FID=$(lfs path2fid $DIR/$tdir/f)
28933         # rmfid w/o user_fid2path mount option should fail
28934         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28935         cnt=$(ls -1 $DIR/$tdir | wc -l)
28936         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28937
28938         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28939         stack_trap "rmdir $tmpdir"
28940         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28941                 error "failed to mount client'"
28942         stack_trap "umount_client $tmpdir"
28943
28944         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28945         # rmfid should succeed
28946         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28947         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28948
28949         # rmfid shouldn't allow to remove files due to dir's permission
28950         chmod a+rwx $tmpdir/$tdir
28951         touch $tmpdir/$tdir/f
28952         ls -la $tmpdir/$tdir
28953         FID=$(lfs path2fid $tmpdir/$tdir/f)
28954         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28955         return 0
28956 }
28957 run_test 421f "rmfid checks permissions"
28958
28959 test_421g() {
28960         local cnt
28961         local FIDS
28962
28963         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28964         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28965                 skip "Need MDS version at least 2.12.54"
28966
28967         mkdir -p $DIR/$tdir
28968         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28969         createmany -o $DIR/$tdir/striped_dir/f 512
28970         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28971         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28972
28973         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28974                 sed "s/[/][^:]*://g")
28975
28976         rm -f $DIR/$tdir/striped_dir/f1*
28977         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28978         removed=$((512 - cnt))
28979
28980         # few files have been just removed, so we expect
28981         # rmfid to fail on their fids
28982         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28983         [ $removed != $errors ] && error "$errors != $removed"
28984
28985         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28986         rm -rf $DIR/$tdir
28987         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28988 }
28989 run_test 421g "rmfid to return errors properly"
28990
28991 test_421h() {
28992         local mount_other
28993         local mount_ret
28994         local rmfid_ret
28995         local old_fid
28996         local fidA
28997         local fidB
28998         local fidC
28999         local fidD
29000
29001         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29002                 skip "Need MDS version at least 2.15.53"
29003
29004         test_mkdir $DIR/$tdir
29005         test_mkdir $DIR/$tdir/subdir
29006         touch $DIR/$tdir/subdir/file0
29007         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29008         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29009         rm -f $DIR/$tdir/subdir/file0
29010         touch $DIR/$tdir/subdir/fileA
29011         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29012         echo File $DIR/$tdir/subdir/fileA FID $fidA
29013         touch $DIR/$tdir/subdir/fileB
29014         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29015         echo File $DIR/$tdir/subdir/fileB FID $fidB
29016         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29017         touch $DIR/$tdir/subdir/fileC
29018         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29019         echo File $DIR/$tdir/subdir/fileC FID $fidC
29020         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29021         touch $DIR/$tdir/fileD
29022         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29023         echo File $DIR/$tdir/fileD FID $fidD
29024
29025         # mount another client mount point with subdirectory mount
29026         export FILESET=/$tdir/subdir
29027         mount_other=${MOUNT}_other
29028         mount_client $mount_other ${MOUNT_OPTS}
29029         mount_ret=$?
29030         export FILESET=""
29031         (( mount_ret == 0 )) || error "mount $mount_other failed"
29032
29033         echo Removing FIDs:
29034         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29035         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29036         rmfid_ret=$?
29037
29038         umount_client $mount_other || error "umount $mount_other failed"
29039
29040         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29041
29042         # fileA should have been deleted
29043         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29044
29045         # fileB should have been deleted
29046         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29047
29048         # fileC should not have been deleted, fid also exists outside of fileset
29049         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29050
29051         # fileD should not have been deleted, it exists outside of fileset
29052         stat $DIR/$tdir/fileD || error "fileD deleted"
29053 }
29054 run_test 421h "rmfid with fileset mount"
29055
29056 test_422() {
29057         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29058         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29059         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29060         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29061         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29062
29063         local amc=$(at_max_get client)
29064         local amo=$(at_max_get mds1)
29065         local timeout=`lctl get_param -n timeout`
29066
29067         at_max_set 0 client
29068         at_max_set 0 mds1
29069
29070 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29071         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29072                         fail_val=$(((2*timeout + 10)*1000))
29073         touch $DIR/$tdir/d3/file &
29074         sleep 2
29075 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29076         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29077                         fail_val=$((2*timeout + 5))
29078         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29079         local pid=$!
29080         sleep 1
29081         kill -9 $pid
29082         sleep $((2 * timeout))
29083         echo kill $pid
29084         kill -9 $pid
29085         lctl mark touch
29086         touch $DIR/$tdir/d2/file3
29087         touch $DIR/$tdir/d2/file4
29088         touch $DIR/$tdir/d2/file5
29089
29090         wait
29091         at_max_set $amc client
29092         at_max_set $amo mds1
29093
29094         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29095         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29096                 error "Watchdog is always throttled"
29097 }
29098 run_test 422 "kill a process with RPC in progress"
29099
29100 stat_test() {
29101     df -h $MOUNT &
29102     df -h $MOUNT &
29103     df -h $MOUNT &
29104     df -h $MOUNT &
29105     df -h $MOUNT &
29106     df -h $MOUNT &
29107 }
29108
29109 test_423() {
29110     local _stats
29111     # ensure statfs cache is expired
29112     sleep 2;
29113
29114     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29115     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29116
29117     return 0
29118 }
29119 run_test 423 "statfs should return a right data"
29120
29121 test_424() {
29122 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29123         $LCTL set_param fail_loc=0x80000522
29124         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29125         rm -f $DIR/$tfile
29126 }
29127 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29128
29129 test_425() {
29130         test_mkdir -c -1 $DIR/$tdir
29131         $LFS setstripe -c -1 $DIR/$tdir
29132
29133         lru_resize_disable "" 100
29134         stack_trap "lru_resize_enable" EXIT
29135
29136         sleep 5
29137
29138         for i in $(seq $((MDSCOUNT * 125))); do
29139                 local t=$DIR/$tdir/$tfile_$i
29140
29141                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29142                         error_noexit "Create file $t"
29143         done
29144         stack_trap "rm -rf $DIR/$tdir" EXIT
29145
29146         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29147                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29148                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29149
29150                 [ $lock_count -le $lru_size ] ||
29151                         error "osc lock count $lock_count > lru size $lru_size"
29152         done
29153
29154         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29155                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29156                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29157
29158                 [ $lock_count -le $lru_size ] ||
29159                         error "mdc lock count $lock_count > lru size $lru_size"
29160         done
29161 }
29162 run_test 425 "lock count should not exceed lru size"
29163
29164 test_426() {
29165         splice-test -r $DIR/$tfile
29166         splice-test -rd $DIR/$tfile
29167         splice-test $DIR/$tfile
29168         splice-test -d $DIR/$tfile
29169 }
29170 run_test 426 "splice test on Lustre"
29171
29172 test_427() {
29173         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29174         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29175                 skip "Need MDS version at least 2.12.4"
29176         local log
29177
29178         mkdir $DIR/$tdir
29179         mkdir $DIR/$tdir/1
29180         mkdir $DIR/$tdir/2
29181         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29182         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29183
29184         $LFS getdirstripe $DIR/$tdir/1/dir
29185
29186         #first setfattr for creating updatelog
29187         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29188
29189 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29190         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29191         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29192         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29193
29194         sleep 2
29195         fail mds2
29196         wait_recovery_complete mds2 $((2*TIMEOUT))
29197
29198         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29199         echo $log | grep "get update log failed" &&
29200                 error "update log corruption is detected" || true
29201 }
29202 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29203
29204 test_428() {
29205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29206         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29207                               awk '/^max_cached_mb/ { print $2 }')
29208         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29209
29210         $LCTL set_param -n llite.*.max_cached_mb=64
29211
29212         mkdir $DIR/$tdir
29213         $LFS setstripe -c 1 $DIR/$tdir
29214         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29215         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29216         #test write
29217         for f in $(seq 4); do
29218                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29219         done
29220         wait
29221
29222         cancel_lru_locks osc
29223         # Test read
29224         for f in $(seq 4); do
29225                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29226         done
29227         wait
29228 }
29229 run_test 428 "large block size IO should not hang"
29230
29231 test_429() { # LU-7915 / LU-10948
29232         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29233         local testfile=$DIR/$tfile
29234         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29235         local new_flag=1
29236         local first_rpc
29237         local second_rpc
29238         local third_rpc
29239
29240         $LCTL get_param $ll_opencache_threshold_count ||
29241                 skip "client does not have opencache parameter"
29242
29243         set_opencache $new_flag
29244         stack_trap "restore_opencache"
29245         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29246                 error "enable opencache failed"
29247         touch $testfile
29248         # drop MDC DLM locks
29249         cancel_lru_locks mdc
29250         # clear MDC RPC stats counters
29251         $LCTL set_param $mdc_rpcstats=clear
29252
29253         # According to the current implementation, we need to run 3 times
29254         # open & close file to verify if opencache is enabled correctly.
29255         # 1st, RPCs are sent for lookup/open and open handle is released on
29256         #      close finally.
29257         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29258         #      so open handle won't be released thereafter.
29259         # 3rd, No RPC is sent out.
29260         $MULTIOP $testfile oc || error "multiop failed"
29261         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29262         echo "1st: $first_rpc RPCs in flight"
29263
29264         $MULTIOP $testfile oc || error "multiop failed"
29265         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29266         echo "2nd: $second_rpc RPCs in flight"
29267
29268         $MULTIOP $testfile oc || error "multiop failed"
29269         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29270         echo "3rd: $third_rpc RPCs in flight"
29271
29272         #verify no MDC RPC is sent
29273         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29274 }
29275 run_test 429 "verify if opencache flag on client side does work"
29276
29277 lseek_test_430() {
29278         local offset
29279         local file=$1
29280
29281         # data at [200K, 400K)
29282         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29283                 error "256K->512K dd fails"
29284         # data at [2M, 3M)
29285         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29286                 error "2M->3M dd fails"
29287         # data at [4M, 5M)
29288         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29289                 error "4M->5M dd fails"
29290         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29291         # start at first component hole #1
29292         printf "Seeking hole from 1000 ... "
29293         offset=$(lseek_test -l 1000 $file)
29294         echo $offset
29295         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29296         printf "Seeking data from 1000 ... "
29297         offset=$(lseek_test -d 1000 $file)
29298         echo $offset
29299         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29300
29301         # start at first component data block
29302         printf "Seeking hole from 300000 ... "
29303         offset=$(lseek_test -l 300000 $file)
29304         echo $offset
29305         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29306         printf "Seeking data from 300000 ... "
29307         offset=$(lseek_test -d 300000 $file)
29308         echo $offset
29309         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29310
29311         # start at the first component but beyond end of object size
29312         printf "Seeking hole from 1000000 ... "
29313         offset=$(lseek_test -l 1000000 $file)
29314         echo $offset
29315         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29316         printf "Seeking data from 1000000 ... "
29317         offset=$(lseek_test -d 1000000 $file)
29318         echo $offset
29319         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29320
29321         # start at second component stripe 2 (empty file)
29322         printf "Seeking hole from 1500000 ... "
29323         offset=$(lseek_test -l 1500000 $file)
29324         echo $offset
29325         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29326         printf "Seeking data from 1500000 ... "
29327         offset=$(lseek_test -d 1500000 $file)
29328         echo $offset
29329         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29330
29331         # start at second component stripe 1 (all data)
29332         printf "Seeking hole from 3000000 ... "
29333         offset=$(lseek_test -l 3000000 $file)
29334         echo $offset
29335         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29336         printf "Seeking data from 3000000 ... "
29337         offset=$(lseek_test -d 3000000 $file)
29338         echo $offset
29339         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29340
29341         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29342                 error "2nd dd fails"
29343         echo "Add data block at 640K...1280K"
29344
29345         # start at before new data block, in hole
29346         printf "Seeking hole from 600000 ... "
29347         offset=$(lseek_test -l 600000 $file)
29348         echo $offset
29349         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29350         printf "Seeking data from 600000 ... "
29351         offset=$(lseek_test -d 600000 $file)
29352         echo $offset
29353         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29354
29355         # start at the first component new data block
29356         printf "Seeking hole from 1000000 ... "
29357         offset=$(lseek_test -l 1000000 $file)
29358         echo $offset
29359         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29360         printf "Seeking data from 1000000 ... "
29361         offset=$(lseek_test -d 1000000 $file)
29362         echo $offset
29363         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29364
29365         # start at second component stripe 2, new data
29366         printf "Seeking hole from 1200000 ... "
29367         offset=$(lseek_test -l 1200000 $file)
29368         echo $offset
29369         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29370         printf "Seeking data from 1200000 ... "
29371         offset=$(lseek_test -d 1200000 $file)
29372         echo $offset
29373         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29374
29375         # start beyond file end
29376         printf "Using offset > filesize ... "
29377         lseek_test -l 4000000 $file && error "lseek should fail"
29378         printf "Using offset > filesize ... "
29379         lseek_test -d 4000000 $file && error "lseek should fail"
29380
29381         printf "Done\n\n"
29382 }
29383
29384 test_430a() {
29385         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29386                 skip "MDT does not support SEEK_HOLE"
29387
29388         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29389                 skip "OST does not support SEEK_HOLE"
29390
29391         local file=$DIR/$tdir/$tfile
29392
29393         mkdir -p $DIR/$tdir
29394
29395         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29396         # OST stripe #1 will have continuous data at [1M, 3M)
29397         # OST stripe #2 is empty
29398         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29399         lseek_test_430 $file
29400         rm $file
29401         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29402         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29403         lseek_test_430 $file
29404         rm $file
29405         $LFS setstripe -c2 -S 512K $file
29406         echo "Two stripes, stripe size 512K"
29407         lseek_test_430 $file
29408         rm $file
29409         # FLR with stale mirror
29410         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29411                        -N -c2 -S 1M $file
29412         echo "Mirrored file:"
29413         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29414         echo "Plain 2 stripes 1M"
29415         lseek_test_430 $file
29416         rm $file
29417 }
29418 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29419
29420 test_430b() {
29421         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29422                 skip "OST does not support SEEK_HOLE"
29423
29424         local offset
29425         local file=$DIR/$tdir/$tfile
29426
29427         mkdir -p $DIR/$tdir
29428         # Empty layout lseek should fail
29429         $MCREATE $file
29430         # seek from 0
29431         printf "Seeking hole from 0 ... "
29432         lseek_test -l 0 $file && error "lseek should fail"
29433         printf "Seeking data from 0 ... "
29434         lseek_test -d 0 $file && error "lseek should fail"
29435         rm $file
29436
29437         # 1M-hole file
29438         $LFS setstripe -E 1M -c2 -E eof $file
29439         $TRUNCATE $file 1048576
29440         printf "Seeking hole from 1000000 ... "
29441         offset=$(lseek_test -l 1000000 $file)
29442         echo $offset
29443         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29444         printf "Seeking data from 1000000 ... "
29445         lseek_test -d 1000000 $file && error "lseek should fail"
29446         rm $file
29447
29448         # full component followed by non-inited one
29449         $LFS setstripe -E 1M -c2 -E eof $file
29450         dd if=/dev/urandom of=$file bs=1M count=1
29451         printf "Seeking hole from 1000000 ... "
29452         offset=$(lseek_test -l 1000000 $file)
29453         echo $offset
29454         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29455         printf "Seeking hole from 1048576 ... "
29456         lseek_test -l 1048576 $file && error "lseek should fail"
29457         # init second component and truncate back
29458         echo "123" >> $file
29459         $TRUNCATE $file 1048576
29460         printf "Seeking hole from 1000000 ... "
29461         offset=$(lseek_test -l 1000000 $file)
29462         echo $offset
29463         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29464         printf "Seeking hole from 1048576 ... "
29465         lseek_test -l 1048576 $file && error "lseek should fail"
29466         # boundary checks for big values
29467         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29468         offset=$(lseek_test -d 0 $file.10g)
29469         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29470         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29471         offset=$(lseek_test -d 0 $file.100g)
29472         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29473         return 0
29474 }
29475 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29476
29477 test_430c() {
29478         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29479                 skip "OST does not support SEEK_HOLE"
29480
29481         local file=$DIR/$tdir/$tfile
29482         local start
29483
29484         mkdir -p $DIR/$tdir
29485         stack_trap "rm -f $file $file.tmp"
29486         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29487
29488         # cp version 8.33+ prefers lseek over fiemap
29489         local ver=$(cp --version | awk '{ print $4; exit; }')
29490
29491         echo "cp $ver installed"
29492         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29493                 start=$SECONDS
29494                 time cp -v $file $file.tmp || error "cp $file failed"
29495                 (( SECONDS - start < 5 )) || {
29496                         strace cp $file $file.tmp |&
29497                                 grep -E "open|read|seek|FIEMAP" |
29498                                 grep -A 100 $file
29499                         error "cp: too long runtime $((SECONDS - start))"
29500                 }
29501         else
29502                 echo "cp test skipped due to $ver < 8.33"
29503         fi
29504
29505         # tar version 1.29+ supports SEEK_HOLE/DATA
29506         ver=$(tar --version | awk '{ print $4; exit; }')
29507         echo "tar $ver installed"
29508         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29509                 start=$SECONDS
29510                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29511                 (( SECONDS - start < 5 )) || {
29512                         strace tar cf $file.tmp --sparse $file |&
29513                                 grep -E "open|read|seek|FIEMAP" |
29514                                 grep -A 100 $file
29515                         error "tar: too long runtime $((SECONDS - start))"
29516                 }
29517         else
29518                 echo "tar test skipped due to $ver < 1.29"
29519         fi
29520 }
29521 run_test 430c "lseek: external tools check"
29522
29523 test_431() { # LU-14187
29524         local file=$DIR/$tdir/$tfile
29525
29526         mkdir -p $DIR/$tdir
29527         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29528         dd if=/dev/urandom of=$file bs=4k count=1
29529         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29530         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29531         #define OBD_FAIL_OST_RESTART_IO 0x251
29532         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29533         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29534         cp $file $file.0
29535         cancel_lru_locks
29536         sync_all_data
29537         echo 3 > /proc/sys/vm/drop_caches
29538         diff  $file $file.0 || error "data diff"
29539 }
29540 run_test 431 "Restart transaction for IO"
29541
29542 cleanup_test_432() {
29543         do_facet mgs $LCTL nodemap_activate 0
29544         wait_nm_sync active
29545 }
29546
29547 test_432() {
29548         local tmpdir=$TMP/dir432
29549
29550         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29551                 skip "Need MDS version at least 2.14.52"
29552
29553         stack_trap cleanup_test_432 EXIT
29554         mkdir $DIR/$tdir
29555         mkdir $tmpdir
29556
29557         do_facet mgs $LCTL nodemap_activate 1
29558         wait_nm_sync active
29559         do_facet mgs $LCTL nodemap_modify --name default \
29560                 --property admin --value 1
29561         do_facet mgs $LCTL nodemap_modify --name default \
29562                 --property trusted --value 1
29563         cancel_lru_locks mdc
29564         wait_nm_sync default admin_nodemap
29565         wait_nm_sync default trusted_nodemap
29566
29567         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29568                grep -ci "Operation not permitted") -ne 0 ]; then
29569                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29570         fi
29571 }
29572 run_test 432 "mv dir from outside Lustre"
29573
29574 test_433() {
29575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29576
29577         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29578                 skip "inode cache not supported"
29579
29580         $LCTL set_param llite.*.inode_cache=0
29581         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29582
29583         local count=256
29584         local before
29585         local after
29586
29587         cancel_lru_locks mdc
29588         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29589         createmany -m $DIR/$tdir/f $count
29590         createmany -d $DIR/$tdir/d $count
29591         ls -l $DIR/$tdir > /dev/null
29592         stack_trap "rm -rf $DIR/$tdir"
29593
29594         before=$(num_objects)
29595         cancel_lru_locks mdc
29596         after=$(num_objects)
29597
29598         # sometimes even @before is less than 2 * count
29599         while (( before - after < count )); do
29600                 sleep 1
29601                 after=$(num_objects)
29602                 wait=$((wait + 1))
29603                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29604                 if (( wait > 60 )); then
29605                         error "inode slab grew from $before to $after"
29606                 fi
29607         done
29608
29609         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29610 }
29611 run_test 433 "ldlm lock cancel releases dentries and inodes"
29612
29613 test_434() {
29614         local file
29615         local getxattr_count
29616         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29618
29619         [[ $(getenforce) == "Disabled" ]] ||
29620                 skip "lsm selinux module have to be disabled for this test"
29621
29622         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29623                 error "fail to create $DIR/$tdir/ on MDT0000"
29624
29625         touch $DIR/$tdir/$tfile-{001..100}
29626
29627         # disable the xattr cache
29628         save_lustre_params client "llite.*.xattr_cache" > $p
29629         lctl set_param llite.*.xattr_cache=0
29630         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29631
29632         # clear clients mdc stats
29633         clear_stats $mdc_stat_param ||
29634                 error "fail to clear stats on mdc MDT0000"
29635
29636         for file in $DIR/$tdir/$tfile-{001..100}; do
29637                 getfattr -n security.selinux $file |&
29638                         grep -q "Operation not supported" ||
29639                         error "getxattr on security.selinux should return EOPNOTSUPP"
29640         done
29641
29642         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29643         (( getxattr_count < 100 )) ||
29644                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29645 }
29646 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29647
29648 test_440() {
29649         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29650                 source $LUSTRE/scripts/bash-completion/lustre
29651         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29652                 source /usr/share/bash-completion/completions/lustre
29653         else
29654                 skip "bash completion scripts not found"
29655         fi
29656
29657         local lctl_completions
29658         local lfs_completions
29659
29660         lctl_completions=$(_lustre_cmds lctl)
29661         if [[ ! $lctl_completions =~ "get_param" ]]; then
29662                 error "lctl bash completion failed"
29663         fi
29664
29665         lfs_completions=$(_lustre_cmds lfs)
29666         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29667                 error "lfs bash completion failed"
29668         fi
29669 }
29670 run_test 440 "bash completion for lfs, lctl"
29671
29672 prep_801() {
29673         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29674         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29675                 skip "Need server version at least 2.9.55"
29676
29677         start_full_debug_logging
29678 }
29679
29680 post_801() {
29681         stop_full_debug_logging
29682 }
29683
29684 barrier_stat() {
29685         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29686                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29687                            awk '/The barrier for/ { print $7 }')
29688                 echo $st
29689         else
29690                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29691                 echo \'$st\'
29692         fi
29693 }
29694
29695 barrier_expired() {
29696         local expired
29697
29698         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29699                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29700                           awk '/will be expired/ { print $7 }')
29701         else
29702                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29703         fi
29704
29705         echo $expired
29706 }
29707
29708 test_801a() {
29709         prep_801
29710
29711         echo "Start barrier_freeze at: $(date)"
29712         #define OBD_FAIL_BARRIER_DELAY          0x2202
29713         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29714         # Do not reduce barrier time - See LU-11873
29715         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29716
29717         sleep 2
29718         local b_status=$(barrier_stat)
29719         echo "Got barrier status at: $(date)"
29720         [ "$b_status" = "'freezing_p1'" ] ||
29721                 error "(1) unexpected barrier status $b_status"
29722
29723         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29724         wait
29725         b_status=$(barrier_stat)
29726         [ "$b_status" = "'frozen'" ] ||
29727                 error "(2) unexpected barrier status $b_status"
29728
29729         local expired=$(barrier_expired)
29730         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29731         sleep $((expired + 3))
29732
29733         b_status=$(barrier_stat)
29734         [ "$b_status" = "'expired'" ] ||
29735                 error "(3) unexpected barrier status $b_status"
29736
29737         # Do not reduce barrier time - See LU-11873
29738         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29739                 error "(4) fail to freeze barrier"
29740
29741         b_status=$(barrier_stat)
29742         [ "$b_status" = "'frozen'" ] ||
29743                 error "(5) unexpected barrier status $b_status"
29744
29745         echo "Start barrier_thaw at: $(date)"
29746         #define OBD_FAIL_BARRIER_DELAY          0x2202
29747         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29748         do_facet mgs $LCTL barrier_thaw $FSNAME &
29749
29750         sleep 2
29751         b_status=$(barrier_stat)
29752         echo "Got barrier status at: $(date)"
29753         [ "$b_status" = "'thawing'" ] ||
29754                 error "(6) unexpected barrier status $b_status"
29755
29756         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29757         wait
29758         b_status=$(barrier_stat)
29759         [ "$b_status" = "'thawed'" ] ||
29760                 error "(7) unexpected barrier status $b_status"
29761
29762         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29763         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29764         do_facet mgs $LCTL barrier_freeze $FSNAME
29765
29766         b_status=$(barrier_stat)
29767         [ "$b_status" = "'failed'" ] ||
29768                 error "(8) unexpected barrier status $b_status"
29769
29770         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29771         do_facet mgs $LCTL barrier_thaw $FSNAME
29772
29773         post_801
29774 }
29775 run_test 801a "write barrier user interfaces and stat machine"
29776
29777 test_801b() {
29778         prep_801
29779
29780         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29781         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29782         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29783         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29784         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29785
29786         cancel_lru_locks mdc
29787
29788         # 180 seconds should be long enough
29789         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29790
29791         local b_status=$(barrier_stat)
29792         [ "$b_status" = "'frozen'" ] ||
29793                 error "(6) unexpected barrier status $b_status"
29794
29795         mkdir $DIR/$tdir/d0/d10 &
29796         mkdir_pid=$!
29797
29798         touch $DIR/$tdir/d1/f13 &
29799         touch_pid=$!
29800
29801         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29802         ln_pid=$!
29803
29804         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29805         mv_pid=$!
29806
29807         rm -f $DIR/$tdir/d4/f12 &
29808         rm_pid=$!
29809
29810         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29811
29812         # To guarantee taht the 'stat' is not blocked
29813         b_status=$(barrier_stat)
29814         [ "$b_status" = "'frozen'" ] ||
29815                 error "(8) unexpected barrier status $b_status"
29816
29817         # let above commands to run at background
29818         sleep 5
29819
29820         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29821         ps -p $touch_pid || error "(10) touch should be blocked"
29822         ps -p $ln_pid || error "(11) link should be blocked"
29823         ps -p $mv_pid || error "(12) rename should be blocked"
29824         ps -p $rm_pid || error "(13) unlink should be blocked"
29825
29826         b_status=$(barrier_stat)
29827         [ "$b_status" = "'frozen'" ] ||
29828                 error "(14) unexpected barrier status $b_status"
29829
29830         do_facet mgs $LCTL barrier_thaw $FSNAME
29831         b_status=$(barrier_stat)
29832         [ "$b_status" = "'thawed'" ] ||
29833                 error "(15) unexpected barrier status $b_status"
29834
29835         wait $mkdir_pid || error "(16) mkdir should succeed"
29836         wait $touch_pid || error "(17) touch should succeed"
29837         wait $ln_pid || error "(18) link should succeed"
29838         wait $mv_pid || error "(19) rename should succeed"
29839         wait $rm_pid || error "(20) unlink should succeed"
29840
29841         post_801
29842 }
29843 run_test 801b "modification will be blocked by write barrier"
29844
29845 test_801c() {
29846         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29847
29848         prep_801
29849
29850         stop mds2 || error "(1) Fail to stop mds2"
29851
29852         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29853
29854         local b_status=$(barrier_stat)
29855         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29856                 do_facet mgs $LCTL barrier_thaw $FSNAME
29857                 error "(2) unexpected barrier status $b_status"
29858         }
29859
29860         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29861                 error "(3) Fail to rescan barrier bitmap"
29862
29863         # Do not reduce barrier time - See LU-11873
29864         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29865
29866         b_status=$(barrier_stat)
29867         [ "$b_status" = "'frozen'" ] ||
29868                 error "(4) unexpected barrier status $b_status"
29869
29870         do_facet mgs $LCTL barrier_thaw $FSNAME
29871         b_status=$(barrier_stat)
29872         [ "$b_status" = "'thawed'" ] ||
29873                 error "(5) unexpected barrier status $b_status"
29874
29875         local devname=$(mdsdevname 2)
29876
29877         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29878
29879         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29880                 error "(7) Fail to rescan barrier bitmap"
29881
29882         post_801
29883 }
29884 run_test 801c "rescan barrier bitmap"
29885
29886 test_802b() {
29887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29888         remote_mds_nodsh && skip "remote MDS with nodsh"
29889
29890         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29891                 skip "readonly option not available"
29892
29893         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29894
29895         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29896                 error "(2) Fail to copy"
29897
29898         # write back all cached data before setting MDT to readonly
29899         cancel_lru_locks
29900         sync_all_data
29901
29902         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29903         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29904
29905         echo "Modify should be refused"
29906         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29907
29908         echo "Read should be allowed"
29909         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29910                 error "(7) Read should succeed under ro mode"
29911
29912         # disable readonly
29913         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29914 }
29915 run_test 802b "be able to set MDTs to readonly"
29916
29917 test_803a() {
29918         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29919         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29920                 skip "MDS needs to be newer than 2.10.54"
29921
29922         mkdir_on_mdt0 $DIR/$tdir
29923         # Create some objects on all MDTs to trigger related logs objects
29924         for idx in $(seq $MDSCOUNT); do
29925                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29926                         $DIR/$tdir/dir${idx} ||
29927                         error "Fail to create $DIR/$tdir/dir${idx}"
29928         done
29929
29930         wait_delete_completed # ensure old test cleanups are finished
29931         sleep 3
29932         echo "before create:"
29933         $LFS df -i $MOUNT
29934         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29935
29936         for i in {1..10}; do
29937                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29938                         error "Fail to create $DIR/$tdir/foo$i"
29939         done
29940
29941         # sync ZFS-on-MDS to refresh statfs data
29942         wait_zfs_commit mds1
29943         sleep 3
29944         echo "after create:"
29945         $LFS df -i $MOUNT
29946         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29947
29948         # allow for an llog to be cleaned up during the test
29949         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29950                 error "before ($before_used) + 10 > after ($after_used)"
29951
29952         for i in {1..10}; do
29953                 rm -rf $DIR/$tdir/foo$i ||
29954                         error "Fail to remove $DIR/$tdir/foo$i"
29955         done
29956
29957         # sync ZFS-on-MDS to refresh statfs data
29958         wait_zfs_commit mds1
29959         wait_delete_completed
29960         sleep 3 # avoid MDT return cached statfs
29961         echo "after unlink:"
29962         $LFS df -i $MOUNT
29963         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29964
29965         # allow for an llog to be created during the test
29966         [ $after_used -le $((before_used + 1)) ] ||
29967                 error "after ($after_used) > before ($before_used) + 1"
29968 }
29969 run_test 803a "verify agent object for remote object"
29970
29971 test_803b() {
29972         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29973         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29974                 skip "MDS needs to be newer than 2.13.56"
29975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29976
29977         for i in $(seq 0 $((MDSCOUNT - 1))); do
29978                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29979         done
29980
29981         local before=0
29982         local after=0
29983
29984         local tmp
29985
29986         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29987         for i in $(seq 0 $((MDSCOUNT - 1))); do
29988                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29989                         awk '/getattr/ { print $2 }')
29990                 before=$((before + tmp))
29991         done
29992         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29993         for i in $(seq 0 $((MDSCOUNT - 1))); do
29994                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29995                         awk '/getattr/ { print $2 }')
29996                 after=$((after + tmp))
29997         done
29998
29999         [ $before -eq $after ] || error "getattr count $before != $after"
30000 }
30001 run_test 803b "remote object can getattr from cache"
30002
30003 test_804() {
30004         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30005         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30006                 skip "MDS needs to be newer than 2.10.54"
30007         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30008
30009         mkdir -p $DIR/$tdir
30010         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30011                 error "Fail to create $DIR/$tdir/dir0"
30012
30013         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30014         local dev=$(mdsdevname 2)
30015
30016         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30017                 grep ${fid} || error "NOT found agent entry for dir0"
30018
30019         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30020                 error "Fail to create $DIR/$tdir/dir1"
30021
30022         touch $DIR/$tdir/dir1/foo0 ||
30023                 error "Fail to create $DIR/$tdir/dir1/foo0"
30024         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30025         local rc=0
30026
30027         for idx in $(seq $MDSCOUNT); do
30028                 dev=$(mdsdevname $idx)
30029                 do_facet mds${idx} \
30030                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30031                         grep ${fid} && rc=$idx
30032         done
30033
30034         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30035                 error "Fail to rename foo0 to foo1"
30036         if [ $rc -eq 0 ]; then
30037                 for idx in $(seq $MDSCOUNT); do
30038                         dev=$(mdsdevname $idx)
30039                         do_facet mds${idx} \
30040                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30041                         grep ${fid} && rc=$idx
30042                 done
30043         fi
30044
30045         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30046                 error "Fail to rename foo1 to foo2"
30047         if [ $rc -eq 0 ]; then
30048                 for idx in $(seq $MDSCOUNT); do
30049                         dev=$(mdsdevname $idx)
30050                         do_facet mds${idx} \
30051                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30052                         grep ${fid} && rc=$idx
30053                 done
30054         fi
30055
30056         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30057
30058         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30059                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30060         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30061                 error "Fail to rename foo2 to foo0"
30062         unlink $DIR/$tdir/dir1/foo0 ||
30063                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30064         rm -rf $DIR/$tdir/dir0 ||
30065                 error "Fail to rm $DIR/$tdir/dir0"
30066
30067         for idx in $(seq $MDSCOUNT); do
30068                 rc=0
30069
30070                 stop mds${idx}
30071                 dev=$(mdsdevname $idx)
30072                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30073                         rc=$?
30074                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30075                         error "mount mds$idx failed"
30076                 df $MOUNT > /dev/null 2>&1
30077
30078                 # e2fsck should not return error
30079                 [ $rc -eq 0 ] ||
30080                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30081         done
30082 }
30083 run_test 804 "verify agent entry for remote entry"
30084
30085 cleanup_805() {
30086         do_facet $SINGLEMDS zfs set quota=$old $fsset
30087         unlinkmany $DIR/$tdir/f- 1000000
30088         trap 0
30089 }
30090
30091 test_805() {
30092         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30093         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30094         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30095                 skip "netfree not implemented before 0.7"
30096         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30097                 skip "Need MDS version at least 2.10.57"
30098
30099         local fsset
30100         local freekb
30101         local usedkb
30102         local old
30103         local quota
30104         local pref="osd-zfs.$FSNAME-MDT0000."
30105
30106         # limit available space on MDS dataset to meet nospace issue
30107         # quickly. then ZFS 0.7.2 can use reserved space if asked
30108         # properly (using netfree flag in osd_declare_destroy()
30109         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30110         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30111                 gawk '{print $3}')
30112         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30113         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30114         let "usedkb=usedkb-freekb"
30115         let "freekb=freekb/2"
30116         if let "freekb > 5000"; then
30117                 let "freekb=5000"
30118         fi
30119         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30120         trap cleanup_805 EXIT
30121         mkdir_on_mdt0 $DIR/$tdir
30122         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30123                 error "Can't set PFL layout"
30124         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30125         rm -rf $DIR/$tdir || error "not able to remove"
30126         do_facet $SINGLEMDS zfs set quota=$old $fsset
30127         trap 0
30128 }
30129 run_test 805 "ZFS can remove from full fs"
30130
30131 # Size-on-MDS test
30132 check_lsom_data()
30133 {
30134         local file=$1
30135         local expect=$(stat -c %s $file)
30136
30137         check_lsom_size $1 $expect
30138
30139         local blocks=$($LFS getsom -b $file)
30140         expect=$(stat -c %b $file)
30141         [[ $blocks == $expect ]] ||
30142                 error "$file expected blocks: $expect, got: $blocks"
30143 }
30144
30145 check_lsom_size()
30146 {
30147         local size
30148         local expect=$2
30149
30150         cancel_lru_locks mdc
30151
30152         size=$($LFS getsom -s $1)
30153         [[ $size == $expect ]] ||
30154                 error "$file expected size: $expect, got: $size"
30155 }
30156
30157 test_806() {
30158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30159                 skip "Need MDS version at least 2.11.52"
30160
30161         local bs=1048576
30162
30163         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30164
30165         disable_opencache
30166         stack_trap "restore_opencache"
30167
30168         # single-threaded write
30169         echo "Test SOM for single-threaded write"
30170         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30171                 error "write $tfile failed"
30172         check_lsom_size $DIR/$tfile $bs
30173
30174         local num=32
30175         local size=$(($num * $bs))
30176         local offset=0
30177         local i
30178
30179         echo "Test SOM for single client multi-threaded($num) write"
30180         $TRUNCATE $DIR/$tfile 0
30181         for ((i = 0; i < $num; i++)); do
30182                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30183                 local pids[$i]=$!
30184                 offset=$((offset + $bs))
30185         done
30186         for (( i=0; i < $num; i++ )); do
30187                 wait ${pids[$i]}
30188         done
30189         check_lsom_size $DIR/$tfile $size
30190
30191         $TRUNCATE $DIR/$tfile 0
30192         for ((i = 0; i < $num; i++)); do
30193                 offset=$((offset - $bs))
30194                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30195                 local pids[$i]=$!
30196         done
30197         for (( i=0; i < $num; i++ )); do
30198                 wait ${pids[$i]}
30199         done
30200         check_lsom_size $DIR/$tfile $size
30201
30202         # multi-client writes
30203         num=$(get_node_count ${CLIENTS//,/ })
30204         size=$(($num * $bs))
30205         offset=0
30206         i=0
30207
30208         echo "Test SOM for multi-client ($num) writes"
30209         $TRUNCATE $DIR/$tfile 0
30210         for client in ${CLIENTS//,/ }; do
30211                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30212                 local pids[$i]=$!
30213                 i=$((i + 1))
30214                 offset=$((offset + $bs))
30215         done
30216         for (( i=0; i < $num; i++ )); do
30217                 wait ${pids[$i]}
30218         done
30219         check_lsom_size $DIR/$tfile $offset
30220
30221         i=0
30222         $TRUNCATE $DIR/$tfile 0
30223         for client in ${CLIENTS//,/ }; do
30224                 offset=$((offset - $bs))
30225                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30226                 local pids[$i]=$!
30227                 i=$((i + 1))
30228         done
30229         for (( i=0; i < $num; i++ )); do
30230                 wait ${pids[$i]}
30231         done
30232         check_lsom_size $DIR/$tfile $size
30233
30234         # verify SOM blocks count
30235         echo "Verify SOM block count"
30236         $TRUNCATE $DIR/$tfile 0
30237         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30238                 error "failed to write file $tfile with fdatasync and fstat"
30239         check_lsom_data $DIR/$tfile
30240
30241         $TRUNCATE $DIR/$tfile 0
30242         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30243                 error "failed to write file $tfile with fdatasync"
30244         check_lsom_data $DIR/$tfile
30245
30246         $TRUNCATE $DIR/$tfile 0
30247         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30248                 error "failed to write file $tfile with sync IO"
30249         check_lsom_data $DIR/$tfile
30250
30251         # verify truncate
30252         echo "Test SOM for truncate"
30253         # use ftruncate to sync blocks on close request
30254         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30255         check_lsom_size $DIR/$tfile 16384
30256         check_lsom_data $DIR/$tfile
30257
30258         $TRUNCATE $DIR/$tfile 1234
30259         check_lsom_size $DIR/$tfile 1234
30260         # sync blocks on the MDT
30261         $MULTIOP $DIR/$tfile oc
30262         check_lsom_data $DIR/$tfile
30263 }
30264 run_test 806 "Verify Lazy Size on MDS"
30265
30266 test_807() {
30267         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30268         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30269                 skip "Need MDS version at least 2.11.52"
30270
30271         # Registration step
30272         changelog_register || error "changelog_register failed"
30273         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30274         changelog_users $SINGLEMDS | grep -q $cl_user ||
30275                 error "User $cl_user not found in changelog_users"
30276
30277         rm -rf $DIR/$tdir || error "rm $tdir failed"
30278         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30279         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30280         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30281         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30282                 error "truncate $tdir/trunc failed"
30283
30284         local bs=1048576
30285         echo "Test SOM for single-threaded write with fsync"
30286         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30287                 error "write $tfile failed"
30288         sync;sync;sync
30289
30290         # multi-client wirtes
30291         local num=$(get_node_count ${CLIENTS//,/ })
30292         local offset=0
30293         local i=0
30294
30295         echo "Test SOM for multi-client ($num) writes"
30296         touch $DIR/$tfile || error "touch $tfile failed"
30297         $TRUNCATE $DIR/$tfile 0
30298         for client in ${CLIENTS//,/ }; do
30299                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30300                 local pids[$i]=$!
30301                 i=$((i + 1))
30302                 offset=$((offset + $bs))
30303         done
30304         for (( i=0; i < $num; i++ )); do
30305                 wait ${pids[$i]}
30306         done
30307
30308         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30309         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30310         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30311         check_lsom_data $DIR/$tdir/trunc
30312         check_lsom_data $DIR/$tdir/single_dd
30313         check_lsom_data $DIR/$tfile
30314
30315         rm -rf $DIR/$tdir
30316         # Deregistration step
30317         changelog_deregister || error "changelog_deregister failed"
30318 }
30319 run_test 807 "verify LSOM syncing tool"
30320
30321 check_som_nologged()
30322 {
30323         local lines=$($LFS changelog $FSNAME-MDT0000 |
30324                 grep 'x=trusted.som' | wc -l)
30325         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30326 }
30327
30328 test_808() {
30329         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30330                 skip "Need MDS version at least 2.11.55"
30331
30332         # Registration step
30333         changelog_register || error "changelog_register failed"
30334
30335         touch $DIR/$tfile || error "touch $tfile failed"
30336         check_som_nologged
30337
30338         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30339                 error "write $tfile failed"
30340         check_som_nologged
30341
30342         $TRUNCATE $DIR/$tfile 1234
30343         check_som_nologged
30344
30345         $TRUNCATE $DIR/$tfile 1048576
30346         check_som_nologged
30347
30348         # Deregistration step
30349         changelog_deregister || error "changelog_deregister failed"
30350 }
30351 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30352
30353 check_som_nodata()
30354 {
30355         $LFS getsom $1
30356         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30357 }
30358
30359 test_809() {
30360         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30361                 skip "Need MDS version at least 2.11.56"
30362
30363         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30364                 error "failed to create DoM-only file $DIR/$tfile"
30365         touch $DIR/$tfile || error "touch $tfile failed"
30366         check_som_nodata $DIR/$tfile
30367
30368         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30369                 error "write $tfile failed"
30370         check_som_nodata $DIR/$tfile
30371
30372         $TRUNCATE $DIR/$tfile 1234
30373         check_som_nodata $DIR/$tfile
30374
30375         $TRUNCATE $DIR/$tfile 4097
30376         check_som_nodata $DIR/$file
30377 }
30378 run_test 809 "Verify no SOM xattr store for DoM-only files"
30379
30380 test_810() {
30381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30382         $GSS && skip_env "could not run with gss"
30383         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30384                 skip "OST < 2.12.58 doesn't align checksum"
30385
30386         set_checksums 1
30387         stack_trap "set_checksums $ORIG_CSUM" EXIT
30388         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30389
30390         local csum
30391         local before
30392         local after
30393         for csum in $CKSUM_TYPES; do
30394                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30395                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30396                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30397                         eval set -- $i
30398                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30399                         before=$(md5sum $DIR/$tfile)
30400                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30401                         after=$(md5sum $DIR/$tfile)
30402                         [ "$before" == "$after" ] ||
30403                                 error "$csum: $before != $after bs=$1 seek=$2"
30404                 done
30405         done
30406 }
30407 run_test 810 "partial page writes on ZFS (LU-11663)"
30408
30409 test_812a() {
30410         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30411                 skip "OST < 2.12.51 doesn't support this fail_loc"
30412
30413         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30414         # ensure ost1 is connected
30415         stat $DIR/$tfile >/dev/null || error "can't stat"
30416         wait_osc_import_state client ost1 FULL
30417         # no locks, no reqs to let the connection idle
30418         cancel_lru_locks osc
30419
30420         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30421 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30422         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30423         wait_osc_import_state client ost1 CONNECTING
30424         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30425
30426         stat $DIR/$tfile >/dev/null || error "can't stat file"
30427 }
30428 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30429
30430 test_812b() { # LU-12378
30431         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30432                 skip "OST < 2.12.51 doesn't support this fail_loc"
30433
30434         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30435         # ensure ost1 is connected
30436         stat $DIR/$tfile >/dev/null || error "can't stat"
30437         wait_osc_import_state client ost1 FULL
30438         # no locks, no reqs to let the connection idle
30439         cancel_lru_locks osc
30440
30441         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30442 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30443         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30444         wait_osc_import_state client ost1 CONNECTING
30445         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30446
30447         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30448         wait_osc_import_state client ost1 IDLE
30449 }
30450 run_test 812b "do not drop no resend request for idle connect"
30451
30452 test_812c() {
30453         local old
30454
30455         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30456
30457         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30458         $LFS getstripe $DIR/$tfile
30459         $LCTL set_param osc.*.idle_timeout=10
30460         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30461         # ensure ost1 is connected
30462         stat $DIR/$tfile >/dev/null || error "can't stat"
30463         wait_osc_import_state client ost1 FULL
30464         # no locks, no reqs to let the connection idle
30465         cancel_lru_locks osc
30466
30467 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30468         $LCTL set_param fail_loc=0x80000533
30469         sleep 15
30470         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30471 }
30472 run_test 812c "idle import vs lock enqueue race"
30473
30474 test_813() {
30475         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30476         [ -z "$file_heat_sav" ] && skip "no file heat support"
30477
30478         local readsample
30479         local writesample
30480         local readbyte
30481         local writebyte
30482         local readsample1
30483         local writesample1
30484         local readbyte1
30485         local writebyte1
30486
30487         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30488         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30489
30490         $LCTL set_param -n llite.*.file_heat=1
30491         echo "Turn on file heat"
30492         echo "Period second: $period_second, Decay percentage: $decay_pct"
30493
30494         echo "QQQQ" > $DIR/$tfile
30495         echo "QQQQ" > $DIR/$tfile
30496         echo "QQQQ" > $DIR/$tfile
30497         cat $DIR/$tfile > /dev/null
30498         cat $DIR/$tfile > /dev/null
30499         cat $DIR/$tfile > /dev/null
30500         cat $DIR/$tfile > /dev/null
30501
30502         local out=$($LFS heat_get $DIR/$tfile)
30503
30504         $LFS heat_get $DIR/$tfile
30505         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30506         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30507         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30508         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30509
30510         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30511         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30512         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30513         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30514
30515         sleep $((period_second + 3))
30516         echo "Sleep $((period_second + 3)) seconds..."
30517         # The recursion formula to calculate the heat of the file f is as
30518         # follow:
30519         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30520         # Where Hi is the heat value in the period between time points i*I and
30521         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30522         # to the weight of Ci.
30523         out=$($LFS heat_get $DIR/$tfile)
30524         $LFS heat_get $DIR/$tfile
30525         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30526         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30527         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30528         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30529
30530         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30531                 error "read sample ($readsample) is wrong"
30532         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30533                 error "write sample ($writesample) is wrong"
30534         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30535                 error "read bytes ($readbyte) is wrong"
30536         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30537                 error "write bytes ($writebyte) is wrong"
30538
30539         echo "QQQQ" > $DIR/$tfile
30540         echo "QQQQ" > $DIR/$tfile
30541         echo "QQQQ" > $DIR/$tfile
30542         cat $DIR/$tfile > /dev/null
30543         cat $DIR/$tfile > /dev/null
30544         cat $DIR/$tfile > /dev/null
30545         cat $DIR/$tfile > /dev/null
30546
30547         sleep $((period_second + 3))
30548         echo "Sleep $((period_second + 3)) seconds..."
30549
30550         out=$($LFS heat_get $DIR/$tfile)
30551         $LFS heat_get $DIR/$tfile
30552         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30553         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30554         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30555         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30556
30557         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30558                 4 * $decay_pct) / 100") -eq 1 ] ||
30559                 error "read sample ($readsample1) is wrong"
30560         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30561                 3 * $decay_pct) / 100") -eq 1 ] ||
30562                 error "write sample ($writesample1) is wrong"
30563         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30564                 20 * $decay_pct) / 100") -eq 1 ] ||
30565                 error "read bytes ($readbyte1) is wrong"
30566         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30567                 15 * $decay_pct) / 100") -eq 1 ] ||
30568                 error "write bytes ($writebyte1) is wrong"
30569
30570         echo "Turn off file heat for the file $DIR/$tfile"
30571         $LFS heat_set -o $DIR/$tfile
30572
30573         echo "QQQQ" > $DIR/$tfile
30574         echo "QQQQ" > $DIR/$tfile
30575         echo "QQQQ" > $DIR/$tfile
30576         cat $DIR/$tfile > /dev/null
30577         cat $DIR/$tfile > /dev/null
30578         cat $DIR/$tfile > /dev/null
30579         cat $DIR/$tfile > /dev/null
30580
30581         out=$($LFS heat_get $DIR/$tfile)
30582         $LFS heat_get $DIR/$tfile
30583         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30584         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30585         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30586         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30587
30588         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30589         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30590         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30591         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30592
30593         echo "Trun on file heat for the file $DIR/$tfile"
30594         $LFS heat_set -O $DIR/$tfile
30595
30596         echo "QQQQ" > $DIR/$tfile
30597         echo "QQQQ" > $DIR/$tfile
30598         echo "QQQQ" > $DIR/$tfile
30599         cat $DIR/$tfile > /dev/null
30600         cat $DIR/$tfile > /dev/null
30601         cat $DIR/$tfile > /dev/null
30602         cat $DIR/$tfile > /dev/null
30603
30604         out=$($LFS heat_get $DIR/$tfile)
30605         $LFS heat_get $DIR/$tfile
30606         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30607         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30608         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30609         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30610
30611         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30612         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30613         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30614         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30615
30616         $LFS heat_set -c $DIR/$tfile
30617         $LCTL set_param -n llite.*.file_heat=0
30618         echo "Turn off file heat support for the Lustre filesystem"
30619
30620         echo "QQQQ" > $DIR/$tfile
30621         echo "QQQQ" > $DIR/$tfile
30622         echo "QQQQ" > $DIR/$tfile
30623         cat $DIR/$tfile > /dev/null
30624         cat $DIR/$tfile > /dev/null
30625         cat $DIR/$tfile > /dev/null
30626         cat $DIR/$tfile > /dev/null
30627
30628         out=$($LFS heat_get $DIR/$tfile)
30629         $LFS heat_get $DIR/$tfile
30630         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30631         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30632         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30633         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30634
30635         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30636         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30637         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30638         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30639
30640         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30641         rm -f $DIR/$tfile
30642 }
30643 run_test 813 "File heat verfication"
30644
30645 test_814()
30646 {
30647         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30648         echo -n y >> $DIR/$tfile
30649         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30650         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30651 }
30652 run_test 814 "sparse cp works as expected (LU-12361)"
30653
30654 test_815()
30655 {
30656         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30657         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30658 }
30659 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30660
30661 test_816() {
30662         local ost1_imp=$(get_osc_import_name client ost1)
30663         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30664                          cut -d'.' -f2)
30665
30666         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30667         # ensure ost1 is connected
30668
30669         stat $DIR/$tfile >/dev/null || error "can't stat"
30670         wait_osc_import_state client ost1 FULL
30671         # no locks, no reqs to let the connection idle
30672         cancel_lru_locks osc
30673         lru_resize_disable osc
30674         local before
30675         local now
30676         before=$($LCTL get_param -n \
30677                  ldlm.namespaces.$imp_name.lru_size)
30678
30679         wait_osc_import_state client ost1 IDLE
30680         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30681         now=$($LCTL get_param -n \
30682               ldlm.namespaces.$imp_name.lru_size)
30683         [ $before == $now ] || error "lru_size changed $before != $now"
30684 }
30685 run_test 816 "do not reset lru_resize on idle reconnect"
30686
30687 cleanup_817() {
30688         umount $tmpdir
30689         exportfs -u localhost:$DIR/nfsexp
30690         rm -rf $DIR/nfsexp
30691 }
30692
30693 test_817() {
30694         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30695
30696         mkdir -p $DIR/nfsexp
30697         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30698                 error "failed to export nfs"
30699
30700         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30701         stack_trap cleanup_817 EXIT
30702
30703         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30704                 error "failed to mount nfs to $tmpdir"
30705
30706         cp /bin/true $tmpdir
30707         $DIR/nfsexp/true || error "failed to execute 'true' command"
30708 }
30709 run_test 817 "nfsd won't cache write lock for exec file"
30710
30711 test_818() {
30712         test_mkdir -i0 -c1 $DIR/$tdir
30713         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30714         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30715         stop $SINGLEMDS
30716
30717         # restore osp-syn threads
30718         stack_trap "fail $SINGLEMDS"
30719
30720         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30721         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30722         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30723                 error "start $SINGLEMDS failed"
30724         rm -rf $DIR/$tdir
30725
30726         local testid=$(echo $TESTNAME | tr '_' ' ')
30727
30728         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30729                 grep "run LFSCK" || error "run LFSCK is not suggested"
30730 }
30731 run_test 818 "unlink with failed llog"
30732
30733 test_819a() {
30734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30735         cancel_lru_locks osc
30736         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30737         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30738         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30739         rm -f $TDIR/$tfile
30740 }
30741 run_test 819a "too big niobuf in read"
30742
30743 test_819b() {
30744         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30745         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30747         cancel_lru_locks osc
30748         sleep 1
30749         rm -f $TDIR/$tfile
30750 }
30751 run_test 819b "too big niobuf in write"
30752
30753
30754 function test_820_start_ost() {
30755         sleep 5
30756
30757         for num in $(seq $OSTCOUNT); do
30758                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30759         done
30760 }
30761
30762 test_820() {
30763         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30764
30765         mkdir $DIR/$tdir
30766         umount_client $MOUNT || error "umount failed"
30767         for num in $(seq $OSTCOUNT); do
30768                 stop ost$num
30769         done
30770
30771         # mount client with no active OSTs
30772         # so that the client can't initialize max LOV EA size
30773         # from OSC notifications
30774         mount_client $MOUNT || error "mount failed"
30775         # delay OST starting to keep this 0 max EA size for a while
30776         test_820_start_ost &
30777
30778         # create a directory on MDS2
30779         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30780                 error "Failed to create directory"
30781         # open intent should update default EA size
30782         # see mdc_update_max_ea_from_body()
30783         # notice this is the very first RPC to MDS2
30784         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30785         ret=$?
30786         echo $out
30787         # With SSK, this situation can lead to -EPERM being returned.
30788         # In that case, simply retry.
30789         if [ $ret -ne 0 ] && $SHARED_KEY; then
30790                 if echo "$out" | grep -q "not permitted"; then
30791                         cp /etc/services $DIR/$tdir/mds2
30792                         ret=$?
30793                 fi
30794         fi
30795         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30796 }
30797 run_test 820 "update max EA from open intent"
30798
30799 test_823() {
30800         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30801         local OST_MAX_PRECREATE=20000
30802
30803         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30804                 skip "Need MDS version at least 2.14.56"
30805
30806         save_lustre_params mds1 \
30807                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30808         do_facet $SINGLEMDS "$LCTL set_param -n \
30809                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30810         do_facet $SINGLEMDS "$LCTL set_param -n \
30811                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30812
30813         stack_trap "restore_lustre_params < $p; rm $p"
30814
30815         do_facet $SINGLEMDS "$LCTL set_param -n \
30816                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30817
30818         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30819                       osp.$FSNAME-OST0000*MDT0000.create_count")
30820         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30821                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30822         local expect_count=$(((($max/2)/256) * 256))
30823
30824         log "setting create_count to 100200:"
30825         log " -result- count: $count with max: $max, expecting: $expect_count"
30826
30827         [[ $count -eq expect_count ]] ||
30828                 error "Create count not set to max precreate."
30829 }
30830 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30831
30832 test_831() {
30833         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30834                 skip "Need MDS version 2.14.56"
30835
30836         local sync_changes=$(do_facet $SINGLEMDS \
30837                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30838
30839         [ "$sync_changes" -gt 100 ] &&
30840                 skip "Sync changes $sync_changes > 100 already"
30841
30842         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30843
30844         $LFS mkdir -i 0 $DIR/$tdir
30845         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30846
30847         save_lustre_params mds1 \
30848                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30849         save_lustre_params mds1 \
30850                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30851
30852         do_facet mds1 "$LCTL set_param -n \
30853                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30854                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30855         stack_trap "restore_lustre_params < $p" EXIT
30856
30857         createmany -o $DIR/$tdir/f- 1000
30858         unlinkmany $DIR/$tdir/f- 1000 &
30859         local UNLINK_PID=$!
30860
30861         while sleep 1; do
30862                 sync_changes=$(do_facet mds1 \
30863                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30864                 # the check in the code is racy, fail the test
30865                 # if the value above the limit by 10.
30866                 [ $sync_changes -gt 110 ] && {
30867                         kill -2 $UNLINK_PID
30868                         wait
30869                         error "osp changes throttling failed, $sync_changes>110"
30870                 }
30871                 kill -0 $UNLINK_PID 2> /dev/null || break
30872         done
30873         wait
30874 }
30875 run_test 831 "throttling unlink/setattr queuing on OSP"
30876
30877 test_832() {
30878         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30879         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30880                 skip "Need MDS version 2.15.52+"
30881         is_rmentry_supported || skip "rm_entry not supported"
30882
30883         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30884         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30885         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30886                 error "mkdir remote_dir failed"
30887         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30888                 error "mkdir striped_dir failed"
30889         touch $DIR/$tdir/file || error "touch file failed"
30890         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30891         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30892 }
30893 run_test 832 "lfs rm_entry"
30894
30895 test_833() {
30896         local file=$DIR/$tfile
30897
30898         stack_trap "rm -f $file" EXIT
30899         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30900
30901         local wpid
30902         local rpid
30903         local rpid2
30904
30905         # Buffered I/O write
30906         (
30907                 while [ ! -e $DIR/sanity.833.lck ]; do
30908                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30909                                 error "failed to write $file"
30910                         sleep 0.$((RANDOM % 4 + 1))
30911                 done
30912         )&
30913         wpid=$!
30914
30915         # Buffered I/O read
30916         (
30917                 while [ ! -e $DIR/sanity.833.lck ]; do
30918                         dd if=$file of=/dev/null bs=1M count=50 ||
30919                                 error "failed to read $file"
30920                         sleep 0.$((RANDOM % 4 + 1))
30921                 done
30922         )&
30923         rpid=$!
30924
30925         # Direct I/O read
30926         (
30927                 while [ ! -e $DIR/sanity.833.lck ]; do
30928                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30929                                 error "failed to read $file in direct I/O mode"
30930                         sleep 0.$((RANDOM % 4 + 1))
30931                 done
30932         )&
30933         rpid2=$!
30934
30935         sleep 30
30936         touch $DIR/sanity.833.lck
30937         wait $wpid || error "$?: buffered write failed"
30938         wait $rpid || error "$?: buffered read failed"
30939         wait $rpid2 || error "$?: direct read failed"
30940 }
30941 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30942
30943 #
30944 # tests that do cleanup/setup should be run at the end
30945 #
30946
30947 test_900() {
30948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30949         local ls
30950
30951         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30952         $LCTL set_param fail_loc=0x903
30953
30954         cancel_lru_locks MGC
30955
30956         FAIL_ON_ERROR=true cleanup
30957         FAIL_ON_ERROR=true setup
30958 }
30959 run_test 900 "umount should not race with any mgc requeue thread"
30960
30961 # LUS-6253/LU-11185
30962 test_901() {
30963         local old
30964         local count
30965         local oldc
30966         local newc
30967         local olds
30968         local news
30969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30970
30971         # some get_param have a bug to handle dot in param name
30972         cancel_lru_locks MGC
30973         old=$(mount -t lustre | wc -l)
30974         # 1 config+sptlrpc
30975         # 2 params
30976         # 3 nodemap
30977         # 4 IR
30978         old=$((old * 4))
30979         oldc=0
30980         count=0
30981         while [ $old -ne $oldc ]; do
30982                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30983                 sleep 1
30984                 ((count++))
30985                 if [ $count -ge $TIMEOUT ]; then
30986                         error "too large timeout"
30987                 fi
30988         done
30989         umount_client $MOUNT || error "umount failed"
30990         mount_client $MOUNT || error "mount failed"
30991         cancel_lru_locks MGC
30992         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30993
30994         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30995
30996         return 0
30997 }
30998 run_test 901 "don't leak a mgc lock on client umount"
30999
31000 # LU-13377
31001 test_902() {
31002         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31003                 skip "client does not have LU-13377 fix"
31004         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31005         $LCTL set_param fail_loc=0x1415
31006         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31007         cancel_lru_locks osc
31008         rm -f $DIR/$tfile
31009 }
31010 run_test 902 "test short write doesn't hang lustre"
31011
31012 # LU-14711
31013 test_903() {
31014         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31015         echo "blah" > $DIR/${tfile}-2
31016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31017         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31018         $LCTL set_param fail_loc=0x417 fail_val=20
31019
31020         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31021         sleep 1 # To start the destroy
31022         wait_destroy_complete 150 || error "Destroy taking too long"
31023         cat $DIR/$tfile > /dev/null || error "Evicted"
31024 }
31025 run_test 903 "Test long page discard does not cause evictions"
31026
31027 test_904() {
31028         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31029         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31030                 grep -q project || skip "skip project quota not supported"
31031
31032         local testfile="$DIR/$tdir/$tfile"
31033         local xattr="trusted.projid"
31034         local projid
31035         local mdts=$(comma_list $(mdts_nodes))
31036         local saved=$(do_facet mds1 $LCTL get_param -n \
31037                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31038
31039         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31040         stack_trap "do_nodes $mdts $LCTL set_param \
31041                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31042
31043         mkdir -p $DIR/$tdir
31044         touch $testfile
31045         #hide projid xattr on server
31046         $LFS project -p 1 $testfile ||
31047                 error "set $testfile project id failed"
31048         getfattr -m - $testfile | grep $xattr &&
31049                 error "do not show trusted.projid when disabled on server"
31050         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31051         #should be hidden when projid is 0
31052         $LFS project -p 0 $testfile ||
31053                 error "set $testfile project id failed"
31054         getfattr -m - $testfile | grep $xattr &&
31055                 error "do not show trusted.projid with project ID 0"
31056
31057         #still can getxattr explicitly
31058         projid=$(getfattr -n $xattr $testfile |
31059                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31060         [ $projid == "0" ] ||
31061                 error "projid expected 0 not $projid"
31062
31063         #set the projid via setxattr
31064         setfattr -n $xattr -v "1000" $testfile ||
31065                 error "setattr failed with $?"
31066         projid=($($LFS project $testfile))
31067         [ ${projid[0]} == "1000" ] ||
31068                 error "projid expected 1000 not $projid"
31069
31070         #check the new projid via getxattr
31071         $LFS project -p 1001 $testfile ||
31072                 error "set $testfile project id failed"
31073         getfattr -m - $testfile | grep $xattr ||
31074                 error "should show trusted.projid when project ID != 0"
31075         projid=$(getfattr -n $xattr $testfile |
31076                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31077         [ $projid == "1001" ] ||
31078                 error "projid expected 1001 not $projid"
31079
31080         #try to set invalid projid
31081         setfattr -n $xattr -v "4294967295" $testfile &&
31082                 error "set invalid projid should fail"
31083
31084         #remove the xattr means setting projid to 0
31085         setfattr -x $xattr $testfile ||
31086                 error "setfattr failed with $?"
31087         projid=($($LFS project $testfile))
31088         [ ${projid[0]} == "0" ] ||
31089                 error "projid expected 0 not $projid"
31090
31091         #should be hidden when parent has inherit flag and same projid
31092         $LFS project -srp 1002 $DIR/$tdir ||
31093                 error "set $tdir project id failed"
31094         getfattr -m - $testfile | grep $xattr &&
31095                 error "do not show trusted.projid with inherit flag"
31096
31097         #still can getxattr explicitly
31098         projid=$(getfattr -n $xattr $testfile |
31099                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31100         [ $projid == "1002" ] ||
31101                 error "projid expected 1002 not $projid"
31102 }
31103 run_test 904 "virtual project ID xattr"
31104
31105 # LU-8582
31106 test_905() {
31107         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31108                 skip "need OST version >= 2.15.50.220 for fail_loc"
31109
31110         remote_ost_nodsh && skip "remote OST with nodsh"
31111         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31112
31113         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31114
31115         #define OBD_FAIL_OST_OPCODE 0x253
31116         # OST_LADVISE = 21
31117         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31118         $LFS ladvise -a willread $DIR/$tfile &&
31119                 error "unexpected success of ladvise with fault injection"
31120         $LFS ladvise -a willread $DIR/$tfile |&
31121                 grep -q "Operation not supported"
31122         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31123 }
31124 run_test 905 "bad or new opcode should not stuck client"
31125
31126 test_906() {
31127         grep -q io_uring_setup /proc/kallsyms ||
31128                 skip "Client OS does not support io_uring I/O engine"
31129         io_uring_probe || skip "kernel does not support io_uring fully"
31130         which fio || skip_env "no fio installed"
31131         fio --enghelp | grep -q io_uring ||
31132                 skip_env "fio does not support io_uring I/O engine"
31133
31134         local file=$DIR/$tfile
31135         local ioengine="io_uring"
31136         local numjobs=2
31137         local size=50M
31138
31139         fio --name=seqwrite --ioengine=$ioengine        \
31140                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31141                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31142                 error "fio seqwrite $file failed"
31143
31144         fio --name=seqread --ioengine=$ioengine \
31145                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31146                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31147                 error "fio seqread $file failed"
31148
31149         rm -f $file || error "rm -f $file failed"
31150 }
31151 run_test 906 "Simple test for io_uring I/O engine via fio"
31152
31153 test_907() {
31154         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31155
31156         # set stripe size to max rpc size
31157         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31158         $LFS getstripe $DIR/$tfile
31159 #define OBD_FAIL_OST_EROFS               0x216
31160         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31161
31162         local bs=$((max_pages * PAGE_SIZE / 16))
31163
31164         # write full one stripe and one block
31165         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31166
31167         rm $DIR/$tfile || error "rm failed"
31168 }
31169 run_test 907 "write rpc error during unlink"
31170
31171 complete_test $SECONDS
31172 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31173 check_and_cleanup_lustre
31174 if [ "$I_MOUNTED" != "yes" ]; then
31175         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31176 fi
31177 exit_status