Whamcloud - gitweb
LU-16515 tests: disable sanity test_118c/118d
[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 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-14541 277
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
67 # until the filemap_read() issue is fixed
68 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
69         always_except LU-16101 27J
70 fi
71
72 #                                  5              12     8   12  15   (min)"
73 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
74
75 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
76         #                                               13    (min)"
77         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
78 fi
79
80 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
81         always_except LU-1941 130b 130c 130d 130e 130f 130g
82         always_except LU-9054 312
83 fi
84
85 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
86
87 # Get the SLES distro version
88 #
89 # Returns a version string that should only be used in comparing
90 # strings returned by version_code()
91 sles_version_code()
92 {
93         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
94
95         # All SuSE Linux versions have one decimal. version_code expects two
96         local sles_version=$version.0
97         version_code $sles_version
98 }
99
100 # Check if we are running on Ubuntu or SLES so we can make decisions on
101 # what tests to run
102 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
103         sles_version=$(sles_version_code)
104         [ $sles_version -lt $(version_code 11.4.0) ] &&
105                 always_except LU-4341 170
106
107         [ $sles_version -lt $(version_code 12.0.0) ] &&
108                 always_except LU-3703 234
109
110         [ $sles_version -ge $(version_code 15.4.0) ] &&
111                 always_except LU-16101 27J
112 elif [ -r /etc/os-release ]; then
113         if grep -qi ubuntu /etc/os-release; then
114                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
115                                                 -e 's/^VERSION=//p' \
116                                                 /etc/os-release |
117                                                 awk '{ print $1 }'))
118
119                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
120                         always_except LU-10366 410
121                 fi
122         fi
123 fi
124
125 build_test_filter
126 FAIL_ON_ERROR=false
127
128 cleanup() {
129         echo -n "cln.."
130         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
131         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
132 }
133 setup() {
134         echo -n "mnt.."
135         load_modules
136         setupall || exit 10
137         echo "done"
138 }
139
140 check_swap_layouts_support()
141 {
142         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
143                 skip "Does not support layout lock."
144 }
145
146 check_swap_layout_no_dom()
147 {
148         local FOLDER=$1
149         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
150         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
151 }
152
153 check_and_setup_lustre
154 DIR=${DIR:-$MOUNT}
155 assert_DIR
156
157 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
158
159 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
160 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
161 rm -rf $DIR/[Rdfs][0-9]*
162
163 # $RUNAS_ID may get set incorrectly somewhere else
164 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
165         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
166
167 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
168
169 if [ "${ONLY}" = "MOUNT" ] ; then
170         echo "Lustre is up, please go on"
171         exit
172 fi
173
174 echo "preparing for tests involving mounts"
175 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
176 touch $EXT2_DEV
177 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
178 echo # add a newline after mke2fs.
179
180 umask 077
181
182 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
183 lctl set_param debug=-1 2> /dev/null || true
184 test_0a() {
185         touch $DIR/$tfile
186         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
187         rm $DIR/$tfile
188         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
189 }
190 run_test 0a "touch; rm ====================="
191
192 test_0b() {
193         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
194         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
195 }
196 run_test 0b "chmod 0755 $DIR ============================="
197
198 test_0c() {
199         $LCTL get_param mdc.*.import | grep "state: FULL" ||
200                 error "import not FULL"
201         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
202                 error "bad target"
203 }
204 run_test 0c "check import proc"
205
206 test_0d() { # LU-3397
207         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
208                 skip "proc exports not supported before 2.10.57"
209
210         local mgs_exp="mgs.MGS.exports"
211         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
212         local exp_client_nid
213         local exp_client_version
214         local exp_val
215         local imp_val
216         local temp_imp=$DIR/$tfile.import
217         local temp_exp=$DIR/$tfile.export
218
219         # save mgc import file to $temp_imp
220         $LCTL get_param mgc.*.import | tee $temp_imp
221         # Check if client uuid is found in MGS export
222         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
223                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
224                         $client_uuid ] &&
225                         break;
226         done
227         # save mgs export file to $temp_exp
228         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
229
230         # Compare the value of field "connect_flags"
231         imp_val=$(grep "connect_flags" $temp_imp)
232         exp_val=$(grep "connect_flags" $temp_exp)
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export flags '$exp_val' != import flags '$imp_val'"
235
236         # Compare client versions.  Only compare top-3 fields for compatibility
237         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
238         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
239         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
240         [ "$exp_val" == "$imp_val" ] ||
241                 error "exp version '$exp_client_version'($exp_val) != " \
242                         "'$(lustre_build_version client)'($imp_val)"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_0e() { # LU-13417
247         (( $MDSCOUNT > 1 )) ||
248                 skip "We need at least 2 MDTs for this test"
249
250         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
251                 skip "Need server version at least 2.14.51"
252
253         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
254         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
255
256         [ $default_lmv_count -eq 1 ] ||
257                 error "$MOUNT default stripe count $default_lmv_count"
258
259         [ $default_lmv_index -eq -1 ] ||
260                 error "$MOUNT default stripe index $default_lmv_index"
261
262         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
263         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
264
265         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
266         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
267
268         [ $mdt_index1 -eq $mdt_index2 ] &&
269                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
270
271         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
272 }
273 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
274
275 test_1() {
276         test_mkdir $DIR/$tdir
277         test_mkdir $DIR/$tdir/d2
278         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
279         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
280         rmdir $DIR/$tdir/d2
281         rmdir $DIR/$tdir
282         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
283 }
284 run_test 1 "mkdir; remkdir; rmdir"
285
286 test_2() {
287         test_mkdir $DIR/$tdir
288         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
292 }
293 run_test 2 "mkdir; touch; rmdir; check file"
294
295 test_3() {
296         test_mkdir $DIR/$tdir
297         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
298         touch $DIR/$tdir/$tfile
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
302 }
303 run_test 3 "mkdir; touch; rmdir; check dir"
304
305 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
306 test_4() {
307         test_mkdir -i 1 $DIR/$tdir
308
309         touch $DIR/$tdir/$tfile ||
310                 error "Create file under remote directory failed"
311
312         rmdir $DIR/$tdir &&
313                 error "Expect error removing in-use dir $DIR/$tdir"
314
315         test -d $DIR/$tdir || error "Remote directory disappeared"
316
317         rm -rf $DIR/$tdir || error "remove remote dir error"
318 }
319 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
320
321 test_5() {
322         test_mkdir $DIR/$tdir
323         test_mkdir $DIR/$tdir/d2
324         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
325         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
326         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
327 }
328 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
329
330 test_6a() {
331         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
332         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
333         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
334                 error "$tfile does not have perm 0666 or UID $UID"
335         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
336         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
337                 error "$tfile should be 0666 and owned by UID $UID"
338 }
339 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
340
341 test_6c() {
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile
345         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
346         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
347                 error "$tfile should be owned by UID $RUNAS_ID"
348         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
349         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by UID $RUNAS_ID"
351 }
352 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
353
354 test_6e() {
355         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
356
357         touch $DIR/$tfile
358         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
359         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by GID $UID"
361         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
362         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
363                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
364 }
365 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
366
367 test_6g() {
368         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
369
370         test_mkdir $DIR/$tdir
371         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
372         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
373         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
374         test_mkdir $DIR/$tdir/d/subdir
375         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
376                 error "$tdir/d/subdir should be GID $RUNAS_GID"
377         if [[ $MDSCOUNT -gt 1 ]]; then
378                 # check remote dir sgid inherite
379                 $LFS mkdir -i 0 $DIR/$tdir.local ||
380                         error "mkdir $tdir.local failed"
381                 chmod g+s $DIR/$tdir.local ||
382                         error "chmod $tdir.local failed"
383                 chgrp $RUNAS_GID $DIR/$tdir.local ||
384                         error "chgrp $tdir.local failed"
385                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
386                         error "mkdir $tdir.remote failed"
387                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
388                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
389                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
390                         error "$tdir.remote should be mode 02755"
391         fi
392 }
393 run_test 6g "verify new dir in sgid dir inherits group"
394
395 test_6h() { # bug 7331
396         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
397
398         touch $DIR/$tfile || error "touch failed"
399         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
400         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
401                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
402         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
403                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
404 }
405 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
406
407 test_7a() {
408         test_mkdir $DIR/$tdir
409         $MCREATE $DIR/$tdir/$tfile
410         chmod 0666 $DIR/$tdir/$tfile
411         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
412                 error "$tdir/$tfile should be mode 0666"
413 }
414 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
415
416 test_7b() {
417         if [ ! -d $DIR/$tdir ]; then
418                 test_mkdir $DIR/$tdir
419         fi
420         $MCREATE $DIR/$tdir/$tfile
421         echo -n foo > $DIR/$tdir/$tfile
422         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
423         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
424 }
425 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
426
427 test_8() {
428         test_mkdir $DIR/$tdir
429         touch $DIR/$tdir/$tfile
430         chmod 0666 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
432                 error "$tfile mode not 0666"
433 }
434 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
435
436 test_9() {
437         test_mkdir $DIR/$tdir
438         test_mkdir $DIR/$tdir/d2
439         test_mkdir $DIR/$tdir/d2/d3
440         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
441 }
442 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
443
444 test_10() {
445         test_mkdir $DIR/$tdir
446         test_mkdir $DIR/$tdir/d2
447         touch $DIR/$tdir/d2/$tfile
448         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
449                 error "$tdir/d2/$tfile not a file"
450 }
451 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
452
453 test_11() {
454         test_mkdir $DIR/$tdir
455         test_mkdir $DIR/$tdir/d2
456         chmod 0666 $DIR/$tdir/d2
457         chmod 0705 $DIR/$tdir/d2
458         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
459                 error "$tdir/d2 mode not 0705"
460 }
461 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
462
463 test_12() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         chmod 0666 $DIR/$tdir/$tfile
467         chmod 0654 $DIR/$tdir/$tfile
468         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
469                 error "$tdir/d2 mode not 0654"
470 }
471 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
472
473 test_13() {
474         test_mkdir $DIR/$tdir
475         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
476         >  $DIR/$tdir/$tfile
477         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
478                 error "$tdir/$tfile size not 0 after truncate"
479 }
480 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
481
482 test_14() {
483         test_mkdir $DIR/$tdir
484         touch $DIR/$tdir/$tfile
485         rm $DIR/$tdir/$tfile
486         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
487 }
488 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
489
490 test_15() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
494         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
495                 error "$tdir/${tfile_2} not a file after rename"
496         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
497 }
498 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
499
500 test_16() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         rm -rf $DIR/$tdir/$tfile
504         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
505 }
506 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
507
508 test_17a() {
509         test_mkdir $DIR/$tdir
510         touch $DIR/$tdir/$tfile
511         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
512         ls -l $DIR/$tdir
513         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
514                 error "$tdir/l-exist not a symlink"
515         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
516                 error "$tdir/l-exist not referencing a file"
517         rm -f $DIR/$tdir/l-exist
518         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
519 }
520 run_test 17a "symlinks: create, remove (real)"
521
522 test_17b() {
523         test_mkdir $DIR/$tdir
524         ln -s no-such-file $DIR/$tdir/l-dangle
525         ls -l $DIR/$tdir
526         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
527                 error "$tdir/l-dangle not referencing no-such-file"
528         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
529                 error "$tdir/l-dangle not referencing non-existent file"
530         rm -f $DIR/$tdir/l-dangle
531         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
532 }
533 run_test 17b "symlinks: create, remove (dangling)"
534
535 test_17c() { # bug 3440 - don't save failed open RPC for replay
536         test_mkdir $DIR/$tdir
537         ln -s foo $DIR/$tdir/$tfile
538         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
539 }
540 run_test 17c "symlinks: open dangling (should return error)"
541
542 test_17d() {
543         test_mkdir $DIR/$tdir
544         ln -s foo $DIR/$tdir/$tfile
545         touch $DIR/$tdir/$tfile || error "creating to new symlink"
546 }
547 run_test 17d "symlinks: create dangling"
548
549 test_17e() {
550         test_mkdir $DIR/$tdir
551         local foo=$DIR/$tdir/$tfile
552         ln -s $foo $foo || error "create symlink failed"
553         ls -l $foo || error "ls -l failed"
554         ls $foo && error "ls not failed" || true
555 }
556 run_test 17e "symlinks: create recursive symlink (should return error)"
557
558 test_17f() {
559         test_mkdir $DIR/$tdir
560         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
563         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
564         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
565         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
566         ls -l  $DIR/$tdir
567 }
568 run_test 17f "symlinks: long and very long symlink name"
569
570 # str_repeat(S, N) generate a string that is string S repeated N times
571 str_repeat() {
572         local s=$1
573         local n=$2
574         local ret=''
575         while [ $((n -= 1)) -ge 0 ]; do
576                 ret=$ret$s
577         done
578         echo $ret
579 }
580
581 # Long symlinks and LU-2241
582 test_17g() {
583         test_mkdir $DIR/$tdir
584         local TESTS="59 60 61 4094 4095"
585
586         # Fix for inode size boundary in 2.1.4
587         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
588                 TESTS="4094 4095"
589
590         # Patch not applied to 2.2 or 2.3 branches
591         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
592         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
593                 TESTS="4094 4095"
594
595         for i in $TESTS; do
596                 local SYMNAME=$(str_repeat 'x' $i)
597                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
598                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
599         done
600 }
601 run_test 17g "symlinks: really long symlink name and inode boundaries"
602
603 test_17h() { #bug 17378
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         remote_mds_nodsh && skip "remote MDS with nodsh"
606
607         local mdt_idx
608
609         test_mkdir $DIR/$tdir
610         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
611         $LFS setstripe -c -1 $DIR/$tdir
612         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
613         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
614         touch $DIR/$tdir/$tfile || true
615 }
616 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
617
618 test_17i() { #bug 20018
619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
620         remote_mds_nodsh && skip "remote MDS with nodsh"
621
622         local foo=$DIR/$tdir/$tfile
623         local mdt_idx
624
625         test_mkdir -c1 $DIR/$tdir
626         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
627         ln -s $foo $foo || error "create symlink failed"
628 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
629         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
630         ls -l $foo && error "error not detected"
631         return 0
632 }
633 run_test 17i "don't panic on short symlink (should return error)"
634
635 test_17k() { #bug 22301
636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
637         [[ -z "$(which rsync 2>/dev/null)" ]] &&
638                 skip "no rsync command"
639         rsync --help | grep -q xattr ||
640                 skip_env "$(rsync --version | head -n1) does not support xattrs"
641         test_mkdir $DIR/$tdir
642         test_mkdir $DIR/$tdir.new
643         touch $DIR/$tdir/$tfile
644         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
645         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
646                 error "rsync failed with xattrs enabled"
647 }
648 run_test 17k "symlinks: rsync with xattrs enabled"
649
650 test_17l() { # LU-279
651         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
652                 skip "no getfattr command"
653
654         test_mkdir $DIR/$tdir
655         touch $DIR/$tdir/$tfile
656         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
657         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
658                 # -h to not follow symlinks. -m '' to list all the xattrs.
659                 # grep to remove first line: '# file: $path'.
660                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
661                 do
662                         lgetxattr_size_check $path $xattr ||
663                                 error "lgetxattr_size_check $path $xattr failed"
664                 done
665         done
666 }
667 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
668
669 # LU-1540
670 test_17m() {
671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
672         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
673         remote_mds_nodsh && skip "remote MDS with nodsh"
674         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
675         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
676                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
677
678         local short_sym="0123456789"
679         local wdir=$DIR/$tdir
680         local i
681
682         test_mkdir $wdir
683         long_sym=$short_sym
684         # create a long symlink file
685         for ((i = 0; i < 4; ++i)); do
686                 long_sym=${long_sym}${long_sym}
687         done
688
689         echo "create 512 short and long symlink files under $wdir"
690         for ((i = 0; i < 256; ++i)); do
691                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
692                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
693         done
694
695         echo "erase them"
696         rm -f $wdir/*
697         sync
698         wait_delete_completed
699
700         echo "recreate the 512 symlink files with a shorter string"
701         for ((i = 0; i < 512; ++i)); do
702                 # rewrite the symlink file with a shorter string
703                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
704                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
705         done
706
707         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
708
709         echo "stop and checking mds${mds_index}:"
710         # e2fsck should not return error
711         stop mds${mds_index}
712         local devname=$(mdsdevname $mds_index)
713         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
714         rc=$?
715
716         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
717                 error "start mds${mds_index} failed"
718         df $MOUNT > /dev/null 2>&1
719         [ $rc -eq 0 ] ||
720                 error "e2fsck detected error for short/long symlink: rc=$rc"
721         rm -f $wdir/*
722 }
723 run_test 17m "run e2fsck against MDT which contains short/long symlink"
724
725 check_fs_consistency_17n() {
726         local mdt_index
727         local rc=0
728
729         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
730         # so it only check MDT1/MDT2 instead of all of MDTs.
731         for mdt_index in 1 2; do
732                 # e2fsck should not return error
733                 stop mds${mdt_index}
734                 local devname=$(mdsdevname $mdt_index)
735                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
736                         rc=$((rc + $?))
737
738                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
739                         error "mount mds$mdt_index failed"
740                 df $MOUNT > /dev/null 2>&1
741         done
742         return $rc
743 }
744
745 test_17n() {
746         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
748         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
749         remote_mds_nodsh && skip "remote MDS with nodsh"
750         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
751         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
752                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
753
754         local i
755
756         test_mkdir $DIR/$tdir
757         for ((i=0; i<10; i++)); do
758                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
759                         error "create remote dir error $i"
760                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
761                         error "create files under remote dir failed $i"
762         done
763
764         check_fs_consistency_17n ||
765                 error "e2fsck report error after create files under remote dir"
766
767         for ((i = 0; i < 10; i++)); do
768                 rm -rf $DIR/$tdir/remote_dir_${i} ||
769                         error "destroy remote dir error $i"
770         done
771
772         check_fs_consistency_17n ||
773                 error "e2fsck report error after unlink files under remote dir"
774
775         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
776                 skip "lustre < 2.4.50 does not support migrate mv"
777
778         for ((i = 0; i < 10; i++)); do
779                 mkdir -p $DIR/$tdir/remote_dir_${i}
780                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
781                         error "create files under remote dir failed $i"
782                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
783                         error "migrate remote dir error $i"
784         done
785         check_fs_consistency_17n || error "e2fsck report error after migration"
786
787         for ((i = 0; i < 10; i++)); do
788                 rm -rf $DIR/$tdir/remote_dir_${i} ||
789                         error "destroy remote dir error $i"
790         done
791
792         check_fs_consistency_17n || error "e2fsck report error after unlink"
793 }
794 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
795
796 test_17o() {
797         remote_mds_nodsh && skip "remote MDS with nodsh"
798         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
799                 skip "Need MDS version at least 2.3.64"
800
801         local wdir=$DIR/${tdir}o
802         local mdt_index
803         local rc=0
804
805         test_mkdir $wdir
806         touch $wdir/$tfile
807         mdt_index=$($LFS getstripe -m $wdir/$tfile)
808         mdt_index=$((mdt_index + 1))
809
810         cancel_lru_locks mdc
811         #fail mds will wait the failover finish then set
812         #following fail_loc to avoid interfer the recovery process.
813         fail mds${mdt_index}
814
815         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
816         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
817         ls -l $wdir/$tfile && rc=1
818         do_facet mds${mdt_index} lctl set_param fail_loc=0
819         [[ $rc -eq 0 ]] || error "stat file should fail"
820 }
821 run_test 17o "stat file with incompat LMA feature"
822
823 test_18() {
824         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
825         ls $DIR || error "Failed to ls $DIR: $?"
826 }
827 run_test 18 "touch .../f ; ls ... =============================="
828
829 test_19a() {
830         touch $DIR/$tfile
831         ls -l $DIR
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
836
837 test_19b() {
838         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
839 }
840 run_test 19b "ls -l .../f19 (should return error) =============="
841
842 test_19c() {
843         [ $RUNAS_ID -eq $UID ] &&
844                 skip_env "RUNAS_ID = UID = $UID -- skipping"
845
846         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
847 }
848 run_test 19c "$RUNAS touch .../f19 (should return error) =="
849
850 test_19d() {
851         cat $DIR/f19 && error || true
852 }
853 run_test 19d "cat .../f19 (should return error) =============="
854
855 test_20() {
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         touch $DIR/$tfile
859         rm $DIR/$tfile
860         touch $DIR/$tfile
861         rm $DIR/$tfile
862         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
863 }
864 run_test 20 "touch .../f ; ls -l ..."
865
866 test_21() {
867         test_mkdir $DIR/$tdir
868         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
869         ln -s dangle $DIR/$tdir/link
870         echo foo >> $DIR/$tdir/link
871         cat $DIR/$tdir/dangle
872         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
873         $CHECKSTAT -f -t file $DIR/$tdir/link ||
874                 error "$tdir/link not linked to a file"
875 }
876 run_test 21 "write to dangling link"
877
878 test_22() {
879         local wdir=$DIR/$tdir
880         test_mkdir $wdir
881         chown $RUNAS_ID:$RUNAS_GID $wdir
882         (cd $wdir || error "cd $wdir failed";
883                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
884                 $RUNAS tar xf -)
885         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
886         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
887         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
888                 error "checkstat -u failed"
889 }
890 run_test 22 "unpack tar archive as non-root user"
891
892 # was test_23
893 test_23a() {
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
898         openfile -f O_CREAT:O_EXCL $file &&
899                 error "$file recreate succeeded" || true
900 }
901 run_test 23a "O_CREAT|O_EXCL in subdir"
902
903 test_23b() { # bug 18988
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         rm -f $file
908         echo foo > $file || error "write filed"
909         echo bar >> $file || error "append filed"
910         $CHECKSTAT -s 8 $file || error "wrong size"
911         rm $file
912 }
913 run_test 23b "O_APPEND check"
914
915 # LU-9409, size with O_APPEND and tiny writes
916 test_23c() {
917         local file=$DIR/$tfile
918
919         # single dd
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
921         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
922         rm -f $file
923
924         # racing tiny writes
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
927         wait
928         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
929         rm -f $file
930
931         #racing tiny & normal writes
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
934         wait
935         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
936         rm -f $file
937
938         #racing tiny & normal writes 2, ugly numbers
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
940         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
941         wait
942         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
943         rm -f $file
944 }
945 run_test 23c "O_APPEND size checks for tiny writes"
946
947 # LU-11069 file offset is correct after appending writes
948 test_23d() {
949         local file=$DIR/$tfile
950         local offset
951
952         echo CentaurHauls > $file
953         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
954         if ((offset != 26)); then
955                 error "wrong offset, expected 26, got '$offset'"
956         fi
957 }
958 run_test 23d "file offset is correct after appending writes"
959
960 # rename sanity
961 test_24a() {
962         echo '-- same directory rename'
963         test_mkdir $DIR/$tdir
964         touch $DIR/$tdir/$tfile.1
965         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
966         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
967 }
968 run_test 24a "rename file to non-existent target"
969
970 test_24b() {
971         test_mkdir $DIR/$tdir
972         touch $DIR/$tdir/$tfile.{1,2}
973         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
974         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
975         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
976 }
977 run_test 24b "rename file to existing target"
978
979 test_24c() {
980         test_mkdir $DIR/$tdir
981         test_mkdir $DIR/$tdir/d$testnum.1
982         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24c "rename directory to non-existent target"
987
988 test_24d() {
989         test_mkdir -c1 $DIR/$tdir
990         test_mkdir -c1 $DIR/$tdir/d$testnum.1
991         test_mkdir -c1 $DIR/$tdir/d$testnum.2
992         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24d "rename directory to existing target"
997
998 test_24e() {
999         echo '-- cross directory renames --'
1000         test_mkdir $DIR/R5a
1001         test_mkdir $DIR/R5b
1002         touch $DIR/R5a/f
1003         mv $DIR/R5a/f $DIR/R5b/g
1004         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1005         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1006 }
1007 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1008
1009 test_24f() {
1010         test_mkdir $DIR/R6a
1011         test_mkdir $DIR/R6b
1012         touch $DIR/R6a/f $DIR/R6b/g
1013         mv $DIR/R6a/f $DIR/R6b/g
1014         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1015         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1016 }
1017 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1018
1019 test_24g() {
1020         test_mkdir $DIR/R7a
1021         test_mkdir $DIR/R7b
1022         test_mkdir $DIR/R7a/d
1023         mv $DIR/R7a/d $DIR/R7b/e
1024         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1025         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1026 }
1027 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1028
1029 test_24h() {
1030         test_mkdir -c1 $DIR/R8a
1031         test_mkdir -c1 $DIR/R8b
1032         test_mkdir -c1 $DIR/R8a/d
1033         test_mkdir -c1 $DIR/R8b/e
1034         mrename $DIR/R8a/d $DIR/R8b/e
1035         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1036         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1037 }
1038 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1039
1040 test_24i() {
1041         echo "-- rename error cases"
1042         test_mkdir $DIR/R9
1043         test_mkdir $DIR/R9/a
1044         touch $DIR/R9/f
1045         mrename $DIR/R9/f $DIR/R9/a
1046         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1047         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1048         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1049 }
1050 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1051
1052 test_24j() {
1053         test_mkdir $DIR/R10
1054         mrename $DIR/R10/f $DIR/R10/g
1055         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1056         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1057         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1058 }
1059 run_test 24j "source does not exist ============================"
1060
1061 test_24k() {
1062         test_mkdir $DIR/R11a
1063         test_mkdir $DIR/R11a/d
1064         touch $DIR/R11a/f
1065         mv $DIR/R11a/f $DIR/R11a/d
1066         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1067         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1068 }
1069 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1070
1071 # bug 2429 - rename foo foo foo creates invalid file
1072 test_24l() {
1073         f="$DIR/f24l"
1074         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1075 }
1076 run_test 24l "Renaming a file to itself ========================"
1077
1078 test_24m() {
1079         f="$DIR/f24m"
1080         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1081         # on ext3 this does not remove either the source or target files
1082         # though the "expected" operation would be to remove the source
1083         $CHECKSTAT -t file ${f} || error "${f} missing"
1084         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1085 }
1086 run_test 24m "Renaming a file to a hard link to itself ========="
1087
1088 test_24n() {
1089     f="$DIR/f24n"
1090     # this stats the old file after it was renamed, so it should fail
1091     touch ${f}
1092     $CHECKSTAT ${f} || error "${f} missing"
1093     mv ${f} ${f}.rename
1094     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1095     $CHECKSTAT -a ${f} || error "${f} exists"
1096 }
1097 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1098
1099 test_24o() {
1100         test_mkdir $DIR/$tdir
1101         rename_many -s random -v -n 10 $DIR/$tdir
1102 }
1103 run_test 24o "rename of files during htree split"
1104
1105 test_24p() {
1106         test_mkdir $DIR/R12a
1107         test_mkdir $DIR/R12b
1108         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1109         mrename $DIR/R12a $DIR/R12b
1110         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1111         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1112         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1113         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1114 }
1115 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1116
1117 cleanup_multiop_pause() {
1118         trap 0
1119         kill -USR1 $MULTIPID
1120 }
1121
1122 test_24q() {
1123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1124
1125         test_mkdir $DIR/R13a
1126         test_mkdir $DIR/R13b
1127         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1128         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1129         MULTIPID=$!
1130
1131         trap cleanup_multiop_pause EXIT
1132         mrename $DIR/R13a $DIR/R13b
1133         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1134         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1135         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1136         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1137         cleanup_multiop_pause
1138         wait $MULTIPID || error "multiop close failed"
1139 }
1140 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1141
1142 test_24r() { #bug 3789
1143         test_mkdir $DIR/R14a
1144         test_mkdir $DIR/R14a/b
1145         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1147         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1148 }
1149 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1150
1151 test_24s() {
1152         test_mkdir $DIR/R15a
1153         test_mkdir $DIR/R15a/b
1154         test_mkdir $DIR/R15a/b/c
1155         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1157         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1158 }
1159 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1160
1161 test_24t() {
1162         test_mkdir $DIR/R16a
1163         test_mkdir $DIR/R16a/b
1164         test_mkdir $DIR/R16a/b/c
1165         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1167         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1168 }
1169 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1170
1171 test_24u() { # bug12192
1172         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1173         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1174 }
1175 run_test 24u "create stripe file"
1176
1177 simple_cleanup_common() {
1178         local createmany=$1
1179         local rc=0
1180
1181         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1182
1183         local start=$SECONDS
1184
1185         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1186         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1187         rc=$?
1188         wait_delete_completed
1189         echo "cleanup time $((SECONDS - start))"
1190         return $rc
1191 }
1192
1193 max_pages_per_rpc() {
1194         local mdtname="$(printf "MDT%04x" ${1:-0})"
1195         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1196 }
1197
1198 test_24v() {
1199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1200
1201         local nrfiles=${COUNT:-100000}
1202         local fname="$DIR/$tdir/$tfile"
1203
1204         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1205         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1206
1207         test_mkdir "$(dirname $fname)"
1208         # assume MDT0000 has the fewest inodes
1209         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1210         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1211         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1212
1213         stack_trap "simple_cleanup_common $nrfiles"
1214
1215         createmany -m "$fname" $nrfiles
1216
1217         cancel_lru_locks mdc
1218         lctl set_param mdc.*.stats clear
1219
1220         # was previously test_24D: LU-6101
1221         # readdir() returns correct number of entries after cursor reload
1222         local num_ls=$(ls $DIR/$tdir | wc -l)
1223         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1224         local num_all=$(ls -a $DIR/$tdir | wc -l)
1225         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1226                 [ $num_all -ne $((nrfiles + 2)) ]; then
1227                         error "Expected $nrfiles files, got $num_ls " \
1228                                 "($num_uniq unique $num_all .&..)"
1229         fi
1230         # LU-5 large readdir
1231         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1232         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1233         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1234         # take into account of overhead in lu_dirpage header and end mark in
1235         # each page, plus one in rpc_num calculation.
1236         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1237         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1238         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1239         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1240         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1241         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1242         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1243         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1244                 error "large readdir doesn't take effect: " \
1245                       "$mds_readpage should be about $rpc_max"
1246 }
1247 run_test 24v "list large directory (test hash collision, b=17560)"
1248
1249 test_24w() { # bug21506
1250         SZ1=234852
1251         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1252         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1253         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1254         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1255         [[ "$SZ1" -eq "$SZ2" ]] ||
1256                 error "Error reading at the end of the file $tfile"
1257 }
1258 run_test 24w "Reading a file larger than 4Gb"
1259
1260 test_24x() {
1261         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1263         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1264                 skip "Need MDS version at least 2.7.56"
1265
1266         local MDTIDX=1
1267         local remote_dir=$DIR/$tdir/remote_dir
1268
1269         test_mkdir $DIR/$tdir
1270         $LFS mkdir -i $MDTIDX $remote_dir ||
1271                 error "create remote directory failed"
1272
1273         test_mkdir $DIR/$tdir/src_dir
1274         touch $DIR/$tdir/src_file
1275         test_mkdir $remote_dir/tgt_dir
1276         touch $remote_dir/tgt_file
1277
1278         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1279                 error "rename dir cross MDT failed!"
1280
1281         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1282                 error "rename file cross MDT failed!"
1283
1284         touch $DIR/$tdir/ln_file
1285         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1286                 error "ln file cross MDT failed"
1287
1288         rm -rf $DIR/$tdir || error "Can not delete directories"
1289 }
1290 run_test 24x "cross MDT rename/link"
1291
1292 test_24y() {
1293         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1295
1296         local remote_dir=$DIR/$tdir/remote_dir
1297         local mdtidx=1
1298
1299         test_mkdir $DIR/$tdir
1300         $LFS mkdir -i $mdtidx $remote_dir ||
1301                 error "create remote directory failed"
1302
1303         test_mkdir $remote_dir/src_dir
1304         touch $remote_dir/src_file
1305         test_mkdir $remote_dir/tgt_dir
1306         touch $remote_dir/tgt_file
1307
1308         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1309                 error "rename subdir in the same remote dir failed!"
1310
1311         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1312                 error "rename files in the same remote dir failed!"
1313
1314         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1315                 error "link files in the same remote dir failed!"
1316
1317         rm -rf $DIR/$tdir || error "Can not delete directories"
1318 }
1319 run_test 24y "rename/link on the same dir should succeed"
1320
1321 test_24z() {
1322         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1323         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1324                 skip "Need MDS version at least 2.12.51"
1325
1326         local index
1327
1328         for index in 0 1; do
1329                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1330                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1331         done
1332
1333         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1334
1335         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1336         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1337
1338         local mdts=$(comma_list $(mdts_nodes))
1339
1340         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1341         stack_trap "do_nodes $mdts $LCTL \
1342                 set_param mdt.*.enable_remote_rename=1" EXIT
1343
1344         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1345
1346         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1347         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1348 }
1349 run_test 24z "cross-MDT rename is done as cp"
1350
1351 test_24A() { # LU-3182
1352         local NFILES=5000
1353
1354         test_mkdir $DIR/$tdir
1355         stack_trap "simple_cleanup_common $NFILES"
1356         createmany -m $DIR/$tdir/$tfile $NFILES
1357         local t=$(ls $DIR/$tdir | wc -l)
1358         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1359         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1360
1361         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1362                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1363 }
1364 run_test 24A "readdir() returns correct number of entries."
1365
1366 test_24B() { # LU-4805
1367         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1368
1369         local count
1370
1371         test_mkdir $DIR/$tdir
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1373                 error "create striped dir failed"
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 2 ] || error "Expected 2, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/a
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 3 ] || error "Expected 3, got $count"
1382
1383         touch $DIR/$tdir/striped_dir/.f
1384
1385         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1386         [ $count -eq 4 ] || error "Expected 4, got $count"
1387
1388         rm -rf $DIR/$tdir || error "Can not delete directories"
1389 }
1390 run_test 24B "readdir for striped dir return correct number of entries"
1391
1392 test_24C() {
1393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1394
1395         mkdir $DIR/$tdir
1396         mkdir $DIR/$tdir/d0
1397         mkdir $DIR/$tdir/d1
1398
1399         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1400                 error "create striped dir failed"
1401
1402         cd $DIR/$tdir/d0/striped_dir
1403
1404         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1405         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1406         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1407
1408         [ "$d0_ino" = "$parent_ino" ] ||
1409                 error ".. wrong, expect $d0_ino, get $parent_ino"
1410
1411         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1412                 error "mv striped dir failed"
1413
1414         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1415
1416         [ "$d1_ino" = "$parent_ino" ] ||
1417                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1418 }
1419 run_test 24C "check .. in striped dir"
1420
1421 test_24E() {
1422         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1424
1425         mkdir -p $DIR/$tdir
1426         mkdir $DIR/$tdir/src_dir
1427         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1428                 error "create remote source failed"
1429
1430         touch $DIR/$tdir/src_dir/src_child/a
1431
1432         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1433                 error "create remote target dir failed"
1434
1435         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1436                 error "create remote target child failed"
1437
1438         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1439                 error "rename dir cross MDT failed!"
1440
1441         find $DIR/$tdir
1442
1443         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1444                 error "src_child still exists after rename"
1445
1446         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1447                 error "missing file(a) after rename"
1448
1449         rm -rf $DIR/$tdir || error "Can not delete directories"
1450 }
1451 run_test 24E "cross MDT rename/link"
1452
1453 test_24F () {
1454         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1455
1456         local repeats=1000
1457         [ "$SLOW" = "no" ] && repeats=100
1458
1459         mkdir -p $DIR/$tdir
1460
1461         echo "$repeats repeats"
1462         for ((i = 0; i < repeats; i++)); do
1463                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1464                 touch $DIR/$tdir/test/a || error "touch fails"
1465                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1466                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1467         done
1468
1469         true
1470 }
1471 run_test 24F "hash order vs readdir (LU-11330)"
1472
1473 test_24G () {
1474         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1475
1476         local ino1
1477         local ino2
1478
1479         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1480         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1481         touch $DIR/$tdir-0/f1 || error "touch f1"
1482         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1483         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1484         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1485         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1486         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1487 }
1488 run_test 24G "migrate symlink in rename"
1489
1490 test_24H() {
1491         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1492         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1493                 skip "MDT1 should be on another node"
1494
1495         test_mkdir -i 1 -c 1 $DIR/$tdir
1496 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1497         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1498         touch $DIR/$tdir/$tfile || error "touch failed"
1499 }
1500 run_test 24H "repeat FLD_QUERY rpc"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27cg() {
1724         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1725                 skip "server does not support overstriping"
1726         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1727         large_xattr_enabled || skip_env "ea_inode feature disabled"
1728
1729         local osts="0"
1730
1731         for ((i=1;i<1000;i++)); do
1732                 osts+=",$((i % OSTCOUNT))"
1733         done
1734
1735         local mdts=$(comma_list $(mdts_nodes))
1736         local before=$(do_nodes $mdts \
1737                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1738                 awk '/many credits/{print $3}' |
1739                 calc_sum)
1740
1741         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1742         $LFS getstripe $DIR/$tfile | grep stripe
1743
1744         rm -f $DIR/$tfile || error "can't unlink"
1745
1746         after=$(do_nodes $mdts \
1747                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1748                 awk '/many credits/{print $3}' |
1749                 calc_sum)
1750
1751         (( before == after )) ||
1752                 error "too many credits happened: $after > $before"
1753 }
1754 run_test 27cg "1000 shouldn't cause too many credits"
1755
1756 test_27d() {
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1759                 error "setstripe failed"
1760         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1761         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1762 }
1763 run_test 27d "create file with default settings"
1764
1765 test_27e() {
1766         # LU-5839 adds check for existed layout before setting it
1767         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1768                 skip "Need MDS version at least 2.7.56"
1769
1770         test_mkdir $DIR/$tdir
1771         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1772         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1773         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1774 }
1775 run_test 27e "setstripe existing file (should return error)"
1776
1777 test_27f() {
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1780                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1781         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1782                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1783         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1784         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1785 }
1786 run_test 27f "setstripe with bad stripe size (should return error)"
1787
1788 test_27g() {
1789         test_mkdir $DIR/$tdir
1790         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1791         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1792                 error "$DIR/$tdir/$tfile has object"
1793 }
1794 run_test 27g "$LFS getstripe with no objects"
1795
1796 test_27ga() {
1797         test_mkdir $DIR/$tdir
1798         touch $DIR/$tdir/$tfile || error "touch failed"
1799         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1800         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1801         local rc=$?
1802         (( rc == 2 )) || error "getstripe did not return ENOENT"
1803 }
1804 run_test 27ga "$LFS getstripe with missing file (should return error)"
1805
1806 test_27i() {
1807         test_mkdir $DIR/$tdir
1808         touch $DIR/$tdir/$tfile || error "touch failed"
1809         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1810                 error "missing objects"
1811 }
1812 run_test 27i "$LFS getstripe with some objects"
1813
1814 test_27j() {
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1817                 error "setstripe failed" || true
1818 }
1819 run_test 27j "setstripe with bad stripe offset (should return error)"
1820
1821 test_27k() { # bug 2844
1822         test_mkdir $DIR/$tdir
1823         local file=$DIR/$tdir/$tfile
1824         local ll_max_blksize=$((4 * 1024 * 1024))
1825         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1826         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1827         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1828         dd if=/dev/zero of=$file bs=4k count=1
1829         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1830         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1831 }
1832 run_test 27k "limit i_blksize for broken user apps"
1833
1834 test_27l() {
1835         mcreate $DIR/$tfile || error "creating file"
1836         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1837                 error "setstripe should have failed" || true
1838 }
1839 run_test 27l "check setstripe permissions (should return error)"
1840
1841 test_27m() {
1842         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1843
1844         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1845                 skip_env "multiple clients -- skipping"
1846
1847         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1848                    head -n1)
1849         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1850                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1851         fi
1852         stack_trap simple_cleanup_common
1853         test_mkdir $DIR/$tdir
1854         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1855         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1856                 error "dd should fill OST0"
1857         i=2
1858         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1859                 i=$((i + 1))
1860                 [ $i -gt 256 ] && break
1861         done
1862         i=$((i + 1))
1863         touch $DIR/$tdir/$tfile.$i
1864         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1865             awk '{print $1}'| grep -w "0") ] &&
1866                 error "OST0 was full but new created file still use it"
1867         i=$((i + 1))
1868         touch $DIR/$tdir/$tfile.$i
1869         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1870             awk '{print $1}'| grep -w "0") ] &&
1871                 error "OST0 was full but new created file still use it" || true
1872 }
1873 run_test 27m "create file while OST0 was full"
1874
1875 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1876 # if the OST isn't full anymore.
1877 reset_enospc() {
1878         local ostidx=${1:-""}
1879         local delay
1880         local ready
1881         local get_prealloc
1882
1883         local list=$(comma_list $(osts_nodes))
1884         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1885
1886         do_nodes $list lctl set_param fail_loc=0
1887         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1888         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1889                 awk '{print $1 * 2;exit;}')
1890         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1891                         grep -v \"^0$\""
1892         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1893 }
1894
1895 test_27n() {
1896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1898         remote_mds_nodsh && skip "remote MDS with nodsh"
1899         remote_ost_nodsh && skip "remote OST with nodsh"
1900
1901         reset_enospc
1902         rm -f $DIR/$tdir/$tfile
1903         exhaust_precreations 0 0x80000215
1904         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1905         touch $DIR/$tdir/$tfile || error "touch failed"
1906         $LFS getstripe $DIR/$tdir/$tfile
1907         reset_enospc
1908 }
1909 run_test 27n "create file with some full OSTs"
1910
1911 test_27o() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919         exhaust_all_precreations 0x215
1920
1921         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1922
1923         reset_enospc
1924         rm -rf $DIR/$tdir/*
1925 }
1926 run_test 27o "create file with all full OSTs (should error)"
1927
1928 function create_and_checktime() {
1929         local fname=$1
1930         local loops=$2
1931         local i
1932
1933         for ((i=0; i < $loops; i++)); do
1934                 local start=$SECONDS
1935                 multiop $fname-$i Oc
1936                 ((SECONDS-start < TIMEOUT)) ||
1937                         error "creation took " $((SECONDS-$start)) && return 1
1938         done
1939 }
1940
1941 test_27oo() {
1942         local mdts=$(comma_list $(mdts_nodes))
1943
1944         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1945                 skip "Need MDS version at least 2.13.57"
1946
1947         local f0=$DIR/${tfile}-0
1948         local f1=$DIR/${tfile}-1
1949
1950         wait_delete_completed
1951
1952         # refill precreated objects
1953         $LFS setstripe -i0 -c1 $f0
1954
1955         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1956         # force QoS allocation policy
1957         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1958         stack_trap "do_nodes $mdts $LCTL set_param \
1959                 lov.*.qos_threshold_rr=$saved" EXIT
1960         sleep_maxage
1961
1962         # one OST is unavailable, but still have few objects preallocated
1963         stop ost1
1964         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1965                 rm -rf $f1 $DIR/$tdir*" EXIT
1966
1967         for ((i=0; i < 7; i++)); do
1968                 mkdir $DIR/$tdir$i || error "can't create dir"
1969                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1970                         error "can't set striping"
1971         done
1972         for ((i=0; i < 7; i++)); do
1973                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1974         done
1975         wait
1976 }
1977 run_test 27oo "don't let few threads to reserve too many objects"
1978
1979 test_27p() {
1980         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1982         remote_mds_nodsh && skip "remote MDS with nodsh"
1983         remote_ost_nodsh && skip "remote OST with nodsh"
1984
1985         reset_enospc
1986         rm -f $DIR/$tdir/$tfile
1987         test_mkdir $DIR/$tdir
1988
1989         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1990         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1991         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1992
1993         exhaust_precreations 0 0x80000215
1994         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1995         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1996         $LFS getstripe $DIR/$tdir/$tfile
1997
1998         reset_enospc
1999 }
2000 run_test 27p "append to a truncated file with some full OSTs"
2001
2002 test_27q() {
2003         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2005         remote_mds_nodsh && skip "remote MDS with nodsh"
2006         remote_ost_nodsh && skip "remote OST with nodsh"
2007
2008         reset_enospc
2009         rm -f $DIR/$tdir/$tfile
2010
2011         mkdir_on_mdt0 $DIR/$tdir
2012         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2013         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2014                 error "truncate $DIR/$tdir/$tfile failed"
2015         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2016
2017         exhaust_all_precreations 0x215
2018
2019         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2020         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2021
2022         reset_enospc
2023 }
2024 run_test 27q "append to truncated file with all OSTs full (should error)"
2025
2026 test_27r() {
2027         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2029         remote_mds_nodsh && skip "remote MDS with nodsh"
2030         remote_ost_nodsh && skip "remote OST with nodsh"
2031
2032         reset_enospc
2033         rm -f $DIR/$tdir/$tfile
2034         exhaust_precreations 0 0x80000215
2035
2036         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2037
2038         reset_enospc
2039 }
2040 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2041
2042 test_27s() { # bug 10725
2043         test_mkdir $DIR/$tdir
2044         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2045         local stripe_count=0
2046         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2047         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2048                 error "stripe width >= 2^32 succeeded" || true
2049
2050 }
2051 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2052
2053 test_27t() { # bug 10864
2054         WDIR=$(pwd)
2055         WLFS=$(which lfs)
2056         cd $DIR
2057         touch $tfile
2058         $WLFS getstripe $tfile
2059         cd $WDIR
2060 }
2061 run_test 27t "check that utils parse path correctly"
2062
2063 test_27u() { # bug 4900
2064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2065         remote_mds_nodsh && skip "remote MDS with nodsh"
2066
2067         local index
2068         local list=$(comma_list $(mdts_nodes))
2069
2070 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2071         do_nodes $list $LCTL set_param fail_loc=0x139
2072         test_mkdir -p $DIR/$tdir
2073         stack_trap "simple_cleanup_common 1000"
2074         createmany -o $DIR/$tdir/$tfile 1000
2075         do_nodes $list $LCTL set_param fail_loc=0
2076
2077         TLOG=$TMP/$tfile.getstripe
2078         $LFS getstripe $DIR/$tdir > $TLOG
2079         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2080         [[ $OBJS -gt 0 ]] &&
2081                 error "$OBJS objects created on OST-0. See $TLOG" ||
2082                 rm -f $TLOG
2083 }
2084 run_test 27u "skip object creation on OSC w/o objects"
2085
2086 test_27v() { # bug 4900
2087         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2089         remote_mds_nodsh && skip "remote MDS with nodsh"
2090         remote_ost_nodsh && skip "remote OST with nodsh"
2091
2092         exhaust_all_precreations 0x215
2093         reset_enospc
2094
2095         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2096
2097         touch $DIR/$tdir/$tfile
2098         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2099         # all except ost1
2100         for (( i=1; i < OSTCOUNT; i++ )); do
2101                 do_facet ost$i lctl set_param fail_loc=0x705
2102         done
2103         local START=`date +%s`
2104         createmany -o $DIR/$tdir/$tfile 32
2105
2106         local FINISH=`date +%s`
2107         local TIMEOUT=`lctl get_param -n timeout`
2108         local PROCESS=$((FINISH - START))
2109         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2110                error "$FINISH - $START >= $TIMEOUT / 2"
2111         sleep $((TIMEOUT / 2 - PROCESS))
2112         reset_enospc
2113 }
2114 run_test 27v "skip object creation on slow OST"
2115
2116 test_27w() { # bug 10997
2117         test_mkdir $DIR/$tdir
2118         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2119         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2120                 error "stripe size $size != 65536" || true
2121         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2122                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2123 }
2124 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2125
2126 test_27wa() {
2127         [[ $OSTCOUNT -lt 2 ]] &&
2128                 skip_env "skipping multiple stripe count/offset test"
2129
2130         test_mkdir $DIR/$tdir
2131         for i in $(seq 1 $OSTCOUNT); do
2132                 offset=$((i - 1))
2133                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2134                         error "setstripe -c $i -i $offset failed"
2135                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2136                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2137                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2138                 [ $index -ne $offset ] &&
2139                         error "stripe offset $index != $offset" || true
2140         done
2141 }
2142 run_test 27wa "check $LFS setstripe -c -i options"
2143
2144 test_27x() {
2145         remote_ost_nodsh && skip "remote OST with nodsh"
2146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2148
2149         OFFSET=$(($OSTCOUNT - 1))
2150         OSTIDX=0
2151         local OST=$(ostname_from_index $OSTIDX)
2152
2153         test_mkdir $DIR/$tdir
2154         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2155         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2156         sleep_maxage
2157         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2158         for i in $(seq 0 $OFFSET); do
2159                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2160                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2161                 error "OST0 was degraded but new created file still use it"
2162         done
2163         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2164 }
2165 run_test 27x "create files while OST0 is degraded"
2166
2167 test_27y() {
2168         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2169         remote_mds_nodsh && skip "remote MDS with nodsh"
2170         remote_ost_nodsh && skip "remote OST with nodsh"
2171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2172
2173         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2174         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2175                 osp.$mdtosc.prealloc_last_id)
2176         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2177                 osp.$mdtosc.prealloc_next_id)
2178         local fcount=$((last_id - next_id))
2179         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2180         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2181
2182         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2183                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2184         local OST_DEACTIVE_IDX=-1
2185         local OSC
2186         local OSTIDX
2187         local OST
2188
2189         for OSC in $MDS_OSCS; do
2190                 OST=$(osc_to_ost $OSC)
2191                 OSTIDX=$(index_from_ostuuid $OST)
2192                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2193                         OST_DEACTIVE_IDX=$OSTIDX
2194                 fi
2195                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2196                         echo $OSC "is Deactivated:"
2197                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2198                 fi
2199         done
2200
2201         OSTIDX=$(index_from_ostuuid $OST)
2202         test_mkdir $DIR/$tdir
2203         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2204
2205         for OSC in $MDS_OSCS; do
2206                 OST=$(osc_to_ost $OSC)
2207                 OSTIDX=$(index_from_ostuuid $OST)
2208                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2209                         echo $OST "is degraded:"
2210                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2211                                                 obdfilter.$OST.degraded=1
2212                 fi
2213         done
2214
2215         sleep_maxage
2216         createmany -o $DIR/$tdir/$tfile $fcount
2217
2218         for OSC in $MDS_OSCS; do
2219                 OST=$(osc_to_ost $OSC)
2220                 OSTIDX=$(index_from_ostuuid $OST)
2221                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2222                         echo $OST "is recovered from degraded:"
2223                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2224                                                 obdfilter.$OST.degraded=0
2225                 else
2226                         do_facet $SINGLEMDS lctl --device %$OSC activate
2227                 fi
2228         done
2229
2230         # all osp devices get activated, hence -1 stripe count restored
2231         local stripe_count=0
2232
2233         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2234         # devices get activated.
2235         sleep_maxage
2236         $LFS setstripe -c -1 $DIR/$tfile
2237         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2238         rm -f $DIR/$tfile
2239         [ $stripe_count -ne $OSTCOUNT ] &&
2240                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2241         return 0
2242 }
2243 run_test 27y "create files while OST0 is degraded and the rest inactive"
2244
2245 check_seq_oid()
2246 {
2247         log "check file $1"
2248
2249         lmm_count=$($LFS getstripe -c $1)
2250         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2251         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2252
2253         local old_ifs="$IFS"
2254         IFS=$'[:]'
2255         fid=($($LFS path2fid $1))
2256         IFS="$old_ifs"
2257
2258         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2259         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2260
2261         # compare lmm_seq and lu_fid->f_seq
2262         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2263         # compare lmm_object_id and lu_fid->oid
2264         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2265
2266         # check the trusted.fid attribute of the OST objects of the file
2267         local have_obdidx=false
2268         local stripe_nr=0
2269         $LFS getstripe $1 | while read obdidx oid hex seq; do
2270                 # skip lines up to and including "obdidx"
2271                 [ -z "$obdidx" ] && break
2272                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2273                 $have_obdidx || continue
2274
2275                 local ost=$((obdidx + 1))
2276                 local dev=$(ostdevname $ost)
2277                 local oid_hex
2278
2279                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2280
2281                 seq=$(echo $seq | sed -e "s/^0x//g")
2282                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2283                         oid_hex=$(echo $oid)
2284                 else
2285                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2286                 fi
2287                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2288
2289                 local ff=""
2290                 #
2291                 # Don't unmount/remount the OSTs if we don't need to do that.
2292                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2293                 # update too, until that use mount/ll_decode_filter_fid/mount.
2294                 # Re-enable when debugfs will understand new filter_fid.
2295                 #
2296                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2297                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2298                                 $dev 2>/dev/null" | grep "parent=")
2299                 fi
2300                 if [ -z "$ff" ]; then
2301                         stop ost$ost
2302                         mount_fstype ost$ost
2303                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2304                                 $(facet_mntpt ost$ost)/$obj_file)
2305                         unmount_fstype ost$ost
2306                         start ost$ost $dev $OST_MOUNT_OPTS
2307                         clients_up
2308                 fi
2309
2310                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2311
2312                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2313
2314                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2315                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2316                 #
2317                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2318                 #       stripe_size=1048576 component_id=1 component_start=0 \
2319                 #       component_end=33554432
2320                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2321                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2322                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2323                 local ff_pstripe
2324                 if grep -q 'stripe=' <<<$ff; then
2325                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2326                 else
2327                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2328                         # into f_ver in this case.  See comment on ff_parent.
2329                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2330                 fi
2331
2332                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2333                 [ $ff_pseq = $lmm_seq ] ||
2334                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2335                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2336                 [ $ff_poid = $lmm_oid ] ||
2337                         error "FF parent OID $ff_poid != $lmm_oid"
2338                 (($ff_pstripe == $stripe_nr)) ||
2339                         error "FF stripe $ff_pstripe != $stripe_nr"
2340
2341                 stripe_nr=$((stripe_nr + 1))
2342                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2343                         continue
2344                 if grep -q 'stripe_count=' <<<$ff; then
2345                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2346                                             -e 's/ .*//' <<<$ff)
2347                         [ $lmm_count = $ff_scnt ] ||
2348                                 error "FF stripe count $lmm_count != $ff_scnt"
2349                 fi
2350         done
2351 }
2352
2353 test_27z() {
2354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2355         remote_ost_nodsh && skip "remote OST with nodsh"
2356
2357         test_mkdir $DIR/$tdir
2358         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2359                 { error "setstripe -c -1 failed"; return 1; }
2360         # We need to send a write to every object to get parent FID info set.
2361         # This _should_ also work for setattr, but does not currently.
2362         # touch $DIR/$tdir/$tfile-1 ||
2363         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2364                 { error "dd $tfile-1 failed"; return 2; }
2365         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2366                 { error "setstripe -c -1 failed"; return 3; }
2367         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2368                 { error "dd $tfile-2 failed"; return 4; }
2369
2370         # make sure write RPCs have been sent to OSTs
2371         sync; sleep 5; sync
2372
2373         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2374         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2375 }
2376 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2377
2378 test_27A() { # b=19102
2379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2380
2381         save_layout_restore_at_exit $MOUNT
2382         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2383         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2384                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2385         local default_size=$($LFS getstripe -S $MOUNT)
2386         local default_offset=$($LFS getstripe -i $MOUNT)
2387         local dsize=$(do_facet $SINGLEMDS \
2388                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2389         [ $default_size -eq $dsize ] ||
2390                 error "stripe size $default_size != $dsize"
2391         [ $default_offset -eq -1 ] ||
2392                 error "stripe offset $default_offset != -1"
2393 }
2394 run_test 27A "check filesystem-wide default LOV EA values"
2395
2396 test_27B() { # LU-2523
2397         test_mkdir $DIR/$tdir
2398         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2399         touch $DIR/$tdir/f0
2400         # open f1 with O_LOV_DELAY_CREATE
2401         # rename f0 onto f1
2402         # call setstripe ioctl on open file descriptor for f1
2403         # close
2404         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2405                 $DIR/$tdir/f0
2406
2407         rm -f $DIR/$tdir/f1
2408         # open f1 with O_LOV_DELAY_CREATE
2409         # unlink f1
2410         # call setstripe ioctl on open file descriptor for f1
2411         # close
2412         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2413
2414         # Allow multiop to fail in imitation of NFS's busted semantics.
2415         true
2416 }
2417 run_test 27B "call setstripe on open unlinked file/rename victim"
2418
2419 # 27C family tests full striping and overstriping
2420 test_27Ca() { #LU-2871
2421         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2422
2423         declare -a ost_idx
2424         local index
2425         local found
2426         local i
2427         local j
2428
2429         test_mkdir $DIR/$tdir
2430         cd $DIR/$tdir
2431         for i in $(seq 0 $((OSTCOUNT - 1))); do
2432                 # set stripe across all OSTs starting from OST$i
2433                 $LFS setstripe -i $i -c -1 $tfile$i
2434                 # get striping information
2435                 ost_idx=($($LFS getstripe $tfile$i |
2436                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2437                 echo "OST Index: ${ost_idx[*]}"
2438
2439                 # check the layout
2440                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2441                         error "${#ost_idx[@]} != $OSTCOUNT"
2442
2443                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2444                         found=0
2445                         for j in "${ost_idx[@]}"; do
2446                                 if [ $index -eq $j ]; then
2447                                         found=1
2448                                         break
2449                                 fi
2450                         done
2451                         [ $found = 1 ] ||
2452                                 error "Can not find $index in ${ost_idx[*]}"
2453                 done
2454         done
2455 }
2456 run_test 27Ca "check full striping across all OSTs"
2457
2458 test_27Cb() {
2459         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2460                 skip "server does not support overstriping"
2461         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2462                 skip_env "too many osts, skipping"
2463
2464         test_mkdir -p $DIR/$tdir
2465         local setcount=$(($OSTCOUNT * 2))
2466         [ $setcount -lt 160 ] || large_xattr_enabled ||
2467                 skip_env "ea_inode feature disabled"
2468
2469         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2470                 error "setstripe failed"
2471
2472         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2473         [ $count -eq $setcount ] ||
2474                 error "stripe count $count, should be $setcount"
2475
2476         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2477                 error "overstriped should be set in pattern"
2478
2479         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2480                 error "dd failed"
2481 }
2482 run_test 27Cb "more stripes than OSTs with -C"
2483
2484 test_27Cc() {
2485         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2486                 skip "server does not support overstriping"
2487         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2488
2489         test_mkdir -p $DIR/$tdir
2490         local setcount=$(($OSTCOUNT - 1))
2491
2492         [ $setcount -lt 160 ] || large_xattr_enabled ||
2493                 skip_env "ea_inode feature disabled"
2494
2495         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2496                 error "setstripe failed"
2497
2498         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2499         [ $count -eq $setcount ] ||
2500                 error "stripe count $count, should be $setcount"
2501
2502         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2503                 error "overstriped should not be set in pattern"
2504
2505         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2506                 error "dd failed"
2507 }
2508 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2509
2510 test_27Cd() {
2511         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2512                 skip "server does not support overstriping"
2513         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2514         large_xattr_enabled || skip_env "ea_inode feature disabled"
2515
2516         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
2517
2518         test_mkdir -p $DIR/$tdir
2519         local setcount=$LOV_MAX_STRIPE_COUNT
2520
2521         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2522                 error "setstripe failed"
2523
2524         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2525         [ $count -eq $setcount ] ||
2526                 error "stripe count $count, should be $setcount"
2527
2528         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2529                 error "overstriped should be set in pattern"
2530
2531         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2532                 error "dd failed"
2533
2534         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2535 }
2536 run_test 27Cd "test maximum stripe count"
2537
2538 test_27Ce() {
2539         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2540                 skip "server does not support overstriping"
2541         test_mkdir -p $DIR/$tdir
2542
2543         pool_add $TESTNAME || error "Pool creation failed"
2544         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2545
2546         local setcount=8
2547
2548         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2549                 error "setstripe failed"
2550
2551         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2552         [ $count -eq $setcount ] ||
2553                 error "stripe count $count, should be $setcount"
2554
2555         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2556                 error "overstriped should be set in pattern"
2557
2558         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2559                 error "dd failed"
2560
2561         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2562 }
2563 run_test 27Ce "test pool with overstriping"
2564
2565 test_27Cf() {
2566         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2567                 skip "server does not support overstriping"
2568         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2569                 skip_env "too many osts, skipping"
2570
2571         test_mkdir -p $DIR/$tdir
2572
2573         local setcount=$(($OSTCOUNT * 2))
2574         [ $setcount -lt 160 ] || large_xattr_enabled ||
2575                 skip_env "ea_inode feature disabled"
2576
2577         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2578                 error "setstripe failed"
2579
2580         echo 1 > $DIR/$tdir/$tfile
2581
2582         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2583         [ $count -eq $setcount ] ||
2584                 error "stripe count $count, should be $setcount"
2585
2586         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2587                 error "overstriped should be set in pattern"
2588
2589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2590                 error "dd failed"
2591
2592         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2593 }
2594 run_test 27Cf "test default inheritance with overstriping"
2595
2596 test_27D() {
2597         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2598         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2599         remote_mds_nodsh && skip "remote MDS with nodsh"
2600
2601         local POOL=${POOL:-testpool}
2602         local first_ost=0
2603         local last_ost=$(($OSTCOUNT - 1))
2604         local ost_step=1
2605         local ost_list=$(seq $first_ost $ost_step $last_ost)
2606         local ost_range="$first_ost $last_ost $ost_step"
2607
2608         test_mkdir $DIR/$tdir
2609         pool_add $POOL || error "pool_add failed"
2610         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2611
2612         local skip27D
2613         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2614                 skip27D+="-s 29"
2615         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2616                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2617                         skip27D+=" -s 30,31"
2618         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2619           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2620                 skip27D+=" -s 32,33"
2621         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2622                 skip27D+=" -s 34"
2623         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2624                 error "llapi_layout_test failed"
2625
2626         destroy_test_pools || error "destroy test pools failed"
2627 }
2628 run_test 27D "validate llapi_layout API"
2629
2630 # Verify that default_easize is increased from its initial value after
2631 # accessing a widely striped file.
2632 test_27E() {
2633         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2634         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2635                 skip "client does not have LU-3338 fix"
2636
2637         # 72 bytes is the minimum space required to store striping
2638         # information for a file striped across one OST:
2639         # (sizeof(struct lov_user_md_v3) +
2640         #  sizeof(struct lov_user_ost_data_v1))
2641         local min_easize=72
2642         $LCTL set_param -n llite.*.default_easize $min_easize ||
2643                 error "lctl set_param failed"
2644         local easize=$($LCTL get_param -n llite.*.default_easize)
2645
2646         [ $easize -eq $min_easize ] ||
2647                 error "failed to set default_easize"
2648
2649         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2650                 error "setstripe failed"
2651         # In order to ensure stat() call actually talks to MDS we need to
2652         # do something drastic to this file to shake off all lock, e.g.
2653         # rename it (kills lookup lock forcing cache cleaning)
2654         mv $DIR/$tfile $DIR/${tfile}-1
2655         ls -l $DIR/${tfile}-1
2656         rm $DIR/${tfile}-1
2657
2658         easize=$($LCTL get_param -n llite.*.default_easize)
2659
2660         [ $easize -gt $min_easize ] ||
2661                 error "default_easize not updated"
2662 }
2663 run_test 27E "check that default extended attribute size properly increases"
2664
2665 test_27F() { # LU-5346/LU-7975
2666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2667         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2668         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2669                 skip "Need MDS version at least 2.8.51"
2670         remote_ost_nodsh && skip "remote OST with nodsh"
2671
2672         test_mkdir $DIR/$tdir
2673         rm -f $DIR/$tdir/f0
2674         $LFS setstripe -c 2 $DIR/$tdir
2675
2676         # stop all OSTs to reproduce situation for LU-7975 ticket
2677         for num in $(seq $OSTCOUNT); do
2678                 stop ost$num
2679         done
2680
2681         # open/create f0 with O_LOV_DELAY_CREATE
2682         # truncate f0 to a non-0 size
2683         # close
2684         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2685
2686         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2687         # open/write it again to force delayed layout creation
2688         cat /etc/hosts > $DIR/$tdir/f0 &
2689         catpid=$!
2690
2691         # restart OSTs
2692         for num in $(seq $OSTCOUNT); do
2693                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2694                         error "ost$num failed to start"
2695         done
2696
2697         wait $catpid || error "cat failed"
2698
2699         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2700         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2701                 error "wrong stripecount"
2702
2703 }
2704 run_test 27F "Client resend delayed layout creation with non-zero size"
2705
2706 test_27G() { #LU-10629
2707         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2708                 skip "Need MDS version at least 2.11.51"
2709         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2710         remote_mds_nodsh && skip "remote MDS with nodsh"
2711         local POOL=${POOL:-testpool}
2712         local ostrange="0 0 1"
2713
2714         test_mkdir $DIR/$tdir
2715         touch $DIR/$tdir/$tfile.nopool
2716         pool_add $POOL || error "pool_add failed"
2717         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2718         $LFS setstripe -p $POOL $DIR/$tdir
2719
2720         local pool=$($LFS getstripe -p $DIR/$tdir)
2721
2722         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2723         touch $DIR/$tdir/$tfile.default
2724         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2725         $LFS find $DIR/$tdir -type f --pool $POOL
2726         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2727         [[ "$found" == "2" ]] ||
2728                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2729
2730         $LFS setstripe -d $DIR/$tdir
2731
2732         pool=$($LFS getstripe -p -d $DIR/$tdir)
2733
2734         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2735 }
2736 run_test 27G "Clear OST pool from stripe"
2737
2738 test_27H() {
2739         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2740                 skip "Need MDS version newer than 2.11.54"
2741         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2742         test_mkdir $DIR/$tdir
2743         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2744         touch $DIR/$tdir/$tfile
2745         $LFS getstripe -c $DIR/$tdir/$tfile
2746         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2747                 error "two-stripe file doesn't have two stripes"
2748
2749         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2750         $LFS getstripe -y $DIR/$tdir/$tfile
2751         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2752              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2753                 error "expected l_ost_idx: [02]$ not matched"
2754
2755         # make sure ost list has been cleared
2756         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2757         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2758                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2759         touch $DIR/$tdir/f3
2760         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2761 }
2762 run_test 27H "Set specific OSTs stripe"
2763
2764 test_27I() {
2765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2767         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2768                 skip "Need MDS version newer than 2.12.52"
2769         local pool=$TESTNAME
2770         local ostrange="1 1 1"
2771
2772         save_layout_restore_at_exit $MOUNT
2773         $LFS setstripe -c 2 -i 0 $MOUNT
2774         pool_add $pool || error "pool_add failed"
2775         pool_add_targets $pool $ostrange ||
2776                 error "pool_add_targets failed"
2777         test_mkdir $DIR/$tdir
2778         $LFS setstripe -p $pool $DIR/$tdir
2779         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2780         $LFS getstripe $DIR/$tdir/$tfile
2781 }
2782 run_test 27I "check that root dir striping does not break parent dir one"
2783
2784 test_27J() {
2785         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2786                 skip "Need MDS version newer than 2.12.51"
2787
2788         test_mkdir $DIR/$tdir
2789         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2790         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2791
2792         # create foreign file (raw way)
2793         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2794                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2795
2796         ! $LFS setstripe --foreign --flags foo \
2797                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2798                         error "creating $tfile with '--flags foo' should fail"
2799
2800         ! $LFS setstripe --foreign --flags 0xffffffff \
2801                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2802                         error "creating $tfile w/ 0xffffffff flags should fail"
2803
2804         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2805                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2806
2807         # verify foreign file (raw way)
2808         parse_foreign_file -f $DIR/$tdir/$tfile |
2809                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2810                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2811         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2812                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2813         parse_foreign_file -f $DIR/$tdir/$tfile |
2814                 grep "lov_foreign_size: 73" ||
2815                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_type: 1" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2819         parse_foreign_file -f $DIR/$tdir/$tfile |
2820                 grep "lov_foreign_flags: 0x0000DA08" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2822         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_value: 0x" |
2824                 sed -e 's/lov_foreign_value: 0x//')
2825         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2826         [[ $lov = ${lov2// /} ]] ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2828
2829         # create foreign file (lfs + API)
2830         $LFS setstripe --foreign=none --flags 0xda08 \
2831                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2832                 error "$DIR/$tdir/${tfile}2: create failed"
2833
2834         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2835                 grep "lfm_magic:.*0x0BD70BD0" ||
2836                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2837         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2838         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2839                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2840         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2841                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2842         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_flags:.*0x0000DA08" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2845         $LFS getstripe $DIR/$tdir/${tfile}2 |
2846                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2847                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2848
2849         # modify striping should fail
2850         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2851                 error "$DIR/$tdir/$tfile: setstripe should fail"
2852         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2853                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2854
2855         # R/W should fail
2856         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2857         cat $DIR/$tdir/${tfile}2 &&
2858                 error "$DIR/$tdir/${tfile}2: read should fail"
2859         cat /etc/passwd > $DIR/$tdir/$tfile &&
2860                 error "$DIR/$tdir/$tfile: write should fail"
2861         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: write should fail"
2863
2864         # chmod should work
2865         chmod 222 $DIR/$tdir/$tfile ||
2866                 error "$DIR/$tdir/$tfile: chmod failed"
2867         chmod 222 $DIR/$tdir/${tfile}2 ||
2868                 error "$DIR/$tdir/${tfile}2: chmod failed"
2869
2870         # chown should work
2871         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2872                 error "$DIR/$tdir/$tfile: chown failed"
2873         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2874                 error "$DIR/$tdir/${tfile}2: chown failed"
2875
2876         # rename should work
2877         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2878                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2879         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2880                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2881
2882         #remove foreign file
2883         rm $DIR/$tdir/${tfile}.new ||
2884                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2885         rm $DIR/$tdir/${tfile}2.new ||
2886                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2887 }
2888 run_test 27J "basic ops on file with foreign LOV"
2889
2890 test_27K() {
2891         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2892                 skip "Need MDS version newer than 2.12.49"
2893
2894         test_mkdir $DIR/$tdir
2895         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2896         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2897
2898         # create foreign dir (raw way)
2899         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2900                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2901
2902         ! $LFS setdirstripe --foreign --flags foo \
2903                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2904                         error "creating $tdir with '--flags foo' should fail"
2905
2906         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2907                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2908                         error "creating $tdir w/ 0xffffffff flags should fail"
2909
2910         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2911                 error "create_foreign_dir FAILED"
2912
2913         # verify foreign dir (raw way)
2914         parse_foreign_dir -d $DIR/$tdir/$tdir |
2915                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2916                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2917         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2918                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2919         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2920                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2921         parse_foreign_dir -d $DIR/$tdir/$tdir |
2922                 grep "lmv_foreign_flags: 55813$" ||
2923                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2924         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2925                 grep "lmv_foreign_value: 0x" |
2926                 sed 's/lmv_foreign_value: 0x//')
2927         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2928                 sed 's/ //g')
2929         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2930
2931         # create foreign dir (lfs + API)
2932         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2933                 $DIR/$tdir/${tdir}2 ||
2934                 error "$DIR/$tdir/${tdir}2: create failed"
2935
2936         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2937
2938         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2939                 grep "lfm_magic:.*0x0CD50CD0" ||
2940                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2941         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2942         # - sizeof(lfm_type) - sizeof(lfm_flags)
2943         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2944                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2945         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2946                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_flags:.*0x0000DA05" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2950         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2951                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2953
2954         # file create in dir should fail
2955         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2956         touch $DIR/$tdir/${tdir}2/$tfile &&
2957                 error "$DIR/${tdir}2: file create should fail"
2958
2959         # chmod should work
2960         chmod 777 $DIR/$tdir/$tdir ||
2961                 error "$DIR/$tdir: chmod failed"
2962         chmod 777 $DIR/$tdir/${tdir}2 ||
2963                 error "$DIR/${tdir}2: chmod failed"
2964
2965         # chown should work
2966         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2967                 error "$DIR/$tdir: chown failed"
2968         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2969                 error "$DIR/${tdir}2: chown failed"
2970
2971         # rename should work
2972         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2973                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2974         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2975                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2976
2977         #remove foreign dir
2978         rmdir $DIR/$tdir/${tdir}.new ||
2979                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2980         rmdir $DIR/$tdir/${tdir}2.new ||
2981                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2982 }
2983 run_test 27K "basic ops on dir with foreign LMV"
2984
2985 test_27L() {
2986         remote_mds_nodsh && skip "remote MDS with nodsh"
2987
2988         local POOL=${POOL:-$TESTNAME}
2989
2990         pool_add $POOL || error "pool_add failed"
2991
2992         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2993                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2994                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2995 }
2996 run_test 27L "lfs pool_list gives correct pool name"
2997
2998 test_27M() {
2999         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3000                 skip "Need MDS version >= than 2.12.57"
3001         remote_mds_nodsh && skip "remote MDS with nodsh"
3002         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3003
3004         # Set default striping on directory
3005         local setcount=4
3006         local stripe_opt
3007         local mdts=$(comma_list $(mdts_nodes))
3008
3009         # if we run against a 2.12 server which lacks overstring support
3010         # then the connect_flag will not report overstriping, even if client
3011         # is 2.14+
3012         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3013                 stripe_opt="-C $setcount"
3014         elif (( $OSTCOUNT >= $setcount )); then
3015                 stripe_opt="-c $setcount"
3016         else
3017                 skip "server does not support overstriping"
3018         fi
3019
3020         test_mkdir $DIR/$tdir
3021
3022         # Validate existing append_* params and ensure restore
3023         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3024         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3025         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3026
3027         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3028         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3029         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3030
3031         $LFS setstripe $stripe_opt $DIR/$tdir
3032
3033         echo 1 > $DIR/$tdir/${tfile}.1
3034         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3035         [ $count -eq $setcount ] ||
3036                 error "(1) stripe count $count, should be $setcount"
3037
3038         local appendcount=$orig_count
3039         echo 1 >> $DIR/$tdir/${tfile}.2_append
3040         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3041         [ $count -eq $appendcount ] ||
3042                 error "(2)stripe count $count, should be $appendcount for append"
3043
3044         # Disable O_APPEND striping, verify it works
3045         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3046
3047         # Should now get the default striping, which is 4
3048         setcount=4
3049         echo 1 >> $DIR/$tdir/${tfile}.3_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3051         [ $count -eq $setcount ] ||
3052                 error "(3) stripe count $count, should be $setcount"
3053
3054         # Try changing the stripe count for append files
3055         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3056
3057         # Append striping is now 2 (directory default is still 4)
3058         appendcount=2
3059         echo 1 >> $DIR/$tdir/${tfile}.4_append
3060         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3061         [ $count -eq $appendcount ] ||
3062                 error "(4) stripe count $count, should be $appendcount for append"
3063
3064         # Test append stripe count of -1
3065         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3066         appendcount=$OSTCOUNT
3067         echo 1 >> $DIR/$tdir/${tfile}.5
3068         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3069         [ $count -eq $appendcount ] ||
3070                 error "(5) stripe count $count, should be $appendcount for append"
3071
3072         # Set append striping back to default of 1
3073         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3074
3075         # Try a new default striping, PFL + DOM
3076         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3077
3078         # Create normal DOM file, DOM returns stripe count == 0
3079         setcount=0
3080         touch $DIR/$tdir/${tfile}.6
3081         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3082         [ $count -eq $setcount ] ||
3083                 error "(6) stripe count $count, should be $setcount"
3084
3085         # Show
3086         appendcount=1
3087         echo 1 >> $DIR/$tdir/${tfile}.7_append
3088         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3089         [ $count -eq $appendcount ] ||
3090                 error "(7) stripe count $count, should be $appendcount for append"
3091
3092         # Clean up DOM layout
3093         $LFS setstripe -d $DIR/$tdir
3094
3095         save_layout_restore_at_exit $MOUNT
3096         # Now test that append striping works when layout is from root
3097         $LFS setstripe -c 2 $MOUNT
3098         # Make a special directory for this
3099         mkdir $DIR/${tdir}/${tdir}.2
3100
3101         # Verify for normal file
3102         setcount=2
3103         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3104         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3105         [ $count -eq $setcount ] ||
3106                 error "(8) stripe count $count, should be $setcount"
3107
3108         appendcount=1
3109         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3110         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3111         [ $count -eq $appendcount ] ||
3112                 error "(9) stripe count $count, should be $appendcount for append"
3113
3114         # Now test O_APPEND striping with pools
3115         pool_add $TESTNAME || error "pool creation failed"
3116         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3117         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3118
3119         echo 1 >> $DIR/$tdir/${tfile}.10_append
3120
3121         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3122         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3123
3124         # Check that count is still correct
3125         appendcount=1
3126         echo 1 >> $DIR/$tdir/${tfile}.11_append
3127         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3128         [ $count -eq $appendcount ] ||
3129                 error "(11) stripe count $count, should be $appendcount for append"
3130
3131         # Disable O_APPEND stripe count, verify pool works separately
3132         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3133
3134         echo 1 >> $DIR/$tdir/${tfile}.12_append
3135
3136         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3137         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3138
3139         # Remove pool setting, verify it's not applied
3140         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3141
3142         echo 1 >> $DIR/$tdir/${tfile}.13_append
3143
3144         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3145         [ "$pool" = "" ] || error "(13) pool found: $pool"
3146 }
3147 run_test 27M "test O_APPEND striping"
3148
3149 test_27N() {
3150         combined_mgs_mds && skip "needs separate MGS/MDT"
3151
3152         pool_add $TESTNAME || error "pool_add failed"
3153         do_facet mgs "$LCTL pool_list $FSNAME" |
3154                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3155                 error "lctl pool_list on MGS failed"
3156 }
3157 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3158
3159 clean_foreign_symlink() {
3160         trap 0
3161         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3162         for i in $DIR/$tdir/* ; do
3163                 $LFS unlink_foreign $i || true
3164         done
3165 }
3166
3167 test_27O() {
3168         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3169                 skip "Need MDS version newer than 2.12.51"
3170
3171         test_mkdir $DIR/$tdir
3172         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3173         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3174
3175         trap clean_foreign_symlink EXIT
3176
3177         # enable foreign_symlink behaviour
3178         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3179
3180         # foreign symlink LOV format is a partial path by default
3181
3182         # create foreign file (lfs + API)
3183         $LFS setstripe --foreign=symlink --flags 0xda05 \
3184                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3185                 error "$DIR/$tdir/${tfile}: create failed"
3186
3187         $LFS getstripe -v $DIR/$tdir/${tfile} |
3188                 grep "lfm_magic:.*0x0BD70BD0" ||
3189                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3190         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3191                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3192         $LFS getstripe -v $DIR/$tdir/${tfile} |
3193                 grep "lfm_flags:.*0x0000DA05" ||
3194                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3195         $LFS getstripe $DIR/$tdir/${tfile} |
3196                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3197                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3198
3199         # modify striping should fail
3200         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3201                 error "$DIR/$tdir/$tfile: setstripe should fail"
3202
3203         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3204         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3205         cat /etc/passwd > $DIR/$tdir/$tfile &&
3206                 error "$DIR/$tdir/$tfile: write should fail"
3207
3208         # rename should succeed
3209         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/$tfile: rename has failed"
3211
3212         #remove foreign_symlink file should fail
3213         rm $DIR/$tdir/${tfile}.new &&
3214                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3215
3216         #test fake symlink
3217         mkdir /tmp/${uuid1} ||
3218                 error "/tmp/${uuid1}: mkdir has failed"
3219         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3220                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3221         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3222         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3223                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3224         #read should succeed now
3225         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3226                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3227         #write should succeed now
3228         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3229                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3230         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3231                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3232         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3233                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3234
3235         #check that getstripe still works
3236         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3237                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3238
3239         # chmod should still succeed
3240         chmod 644 $DIR/$tdir/${tfile}.new ||
3241                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3242
3243         # chown should still succeed
3244         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3245                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3246
3247         # rename should still succeed
3248         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3249                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3250
3251         #remove foreign_symlink file should still fail
3252         rm $DIR/$tdir/${tfile} &&
3253                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3254
3255         #use special ioctl() to unlink foreign_symlink file
3256         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3257                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3258
3259 }
3260 run_test 27O "basic ops on foreign file of symlink type"
3261
3262 test_27P() {
3263         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3264                 skip "Need MDS version newer than 2.12.49"
3265
3266         test_mkdir $DIR/$tdir
3267         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3268         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3269
3270         trap clean_foreign_symlink EXIT
3271
3272         # enable foreign_symlink behaviour
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3274
3275         # foreign symlink LMV format is a partial path by default
3276
3277         # create foreign dir (lfs + API)
3278         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3279                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3280                 error "$DIR/$tdir/${tdir}: create failed"
3281
3282         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3283
3284         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3285                 grep "lfm_magic:.*0x0CD50CD0" ||
3286                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3287         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3288                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3289         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3290                 grep "lfm_flags:.*0x0000DA05" ||
3291                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3292         $LFS getdirstripe $DIR/$tdir/${tdir} |
3293                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3294                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3295
3296         # file create in dir should fail
3297         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3298         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3299
3300         # rename should succeed
3301         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3302                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3303
3304         #remove foreign_symlink dir should fail
3305         rmdir $DIR/$tdir/${tdir}.new &&
3306                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3307
3308         #test fake symlink
3309         mkdir -p /tmp/${uuid1}/${uuid2} ||
3310                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3311         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3312                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3313         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3314         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3315                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3316         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3317                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3318
3319         #check that getstripe fails now that foreign_symlink enabled
3320         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3321                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3322
3323         # file create in dir should work now
3324         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3325                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3326         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3327                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3328         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3329                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3330
3331         # chmod should still succeed
3332         chmod 755 $DIR/$tdir/${tdir}.new ||
3333                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3334
3335         # chown should still succeed
3336         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3337                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3338
3339         # rename should still succeed
3340         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3341                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3342
3343         #remove foreign_symlink dir should still fail
3344         rmdir $DIR/$tdir/${tdir} &&
3345                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3346
3347         #use special ioctl() to unlink foreign_symlink file
3348         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3349                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3350
3351         #created file should still exist
3352         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3353                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3354         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3355                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3356 }
3357 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3358
3359 test_27Q() {
3360         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3361         stack_trap "rm -f $TMP/$tfile*"
3362
3363         test_mkdir $DIR/$tdir-1
3364         test_mkdir $DIR/$tdir-2
3365
3366         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3367         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3368
3369         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3370         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3371
3372         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3373         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3374
3375         # Create some bad symlinks and ensure that we don't loop
3376         # forever or something. These should return ELOOP (40) and
3377         # ENOENT (2) but I don't want to test for that because there's
3378         # always some weirdo architecture that needs to ruin
3379         # everything by defining these error numbers differently.
3380
3381         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3382         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3383
3384         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3385         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3386
3387         return 0
3388 }
3389 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3390
3391 test_27R() {
3392         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3393                 skip "need MDS 2.14.55 or later"
3394         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3395
3396         local testdir="$DIR/$tdir"
3397         test_mkdir -p $testdir
3398         stack_trap "rm -rf $testdir"
3399         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3400
3401         local f1="$testdir/f1"
3402         touch $f1 || error "failed to touch $f1"
3403         local count=$($LFS getstripe -c $f1)
3404         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3405
3406         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3407         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3408
3409         local maxcount=$(($OSTCOUNT - 1))
3410         local mdts=$(comma_list $(mdts_nodes))
3411         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3412         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3413
3414         local f2="$testdir/f2"
3415         touch $f2 || error "failed to touch $f2"
3416         local count=$($LFS getstripe -c $f2)
3417         (( $count == $maxcount )) || error "wrong stripe count"
3418 }
3419 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3420
3421 test_27T() {
3422         [ $(facet_host client) == $(facet_host ost1) ] &&
3423                 skip "need ost1 and client on different nodes"
3424
3425 #define OBD_FAIL_OSC_NO_GRANT            0x411
3426         $LCTL set_param fail_loc=0x20000411 fail_val=1
3427 #define OBD_FAIL_OST_ENOSPC              0x215
3428         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3429         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3430         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3431                 error "multiop failed"
3432 }
3433 run_test 27T "no eio on close on partial write due to enosp"
3434
3435 test_27U() {
3436         local dir=$DIR/$tdir
3437         local file=$dir/$tfile
3438         local append_pool=${TESTNAME}-append
3439         local normal_pool=${TESTNAME}-normal
3440         local pool
3441         local stripe_count
3442         local stripe_count2
3443         local mdts=$(comma_list $(mdts_nodes))
3444
3445         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3446                 skip "Need MDS version at least 2.15.51 for append pool feature"
3447
3448         # Validate existing append_* params and ensure restore
3449         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3450         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3451         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3452
3453         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3454         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3455         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3456
3457         pool_add $append_pool || error "pool creation failed"
3458         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3459
3460         pool_add $normal_pool || error "pool creation failed"
3461         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3462
3463         test_mkdir $dir
3464         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3465
3466         echo XXX >> $file.1
3467         $LFS getstripe $file.1
3468
3469         pool=$($LFS getstripe -p $file.1)
3470         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3471
3472         stripe_count2=$($LFS getstripe -c $file.1)
3473         ((stripe_count2 == stripe_count)) ||
3474                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3475
3476         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3477
3478         echo XXX >> $file.2
3479         $LFS getstripe $file.2
3480
3481         pool=$($LFS getstripe -p $file.2)
3482         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3483
3484         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3485
3486         echo XXX >> $file.3
3487         $LFS getstripe $file.3
3488
3489         stripe_count2=$($LFS getstripe -c $file.3)
3490         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3491 }
3492 run_test 27U "append pool and stripe count work with composite default layout"
3493
3494 # createtest also checks that device nodes are created and
3495 # then visible correctly (#2091)
3496 test_28() { # bug 2091
3497         test_mkdir $DIR/d28
3498         $CREATETEST $DIR/d28/ct || error "createtest failed"
3499 }
3500 run_test 28 "create/mknod/mkdir with bad file types ============"
3501
3502 test_29() {
3503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3504
3505         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3506                 disable_opencache
3507                 stack_trap "restore_opencache"
3508         }
3509
3510         sync; sleep 1; sync # flush out any dirty pages from previous tests
3511         cancel_lru_locks
3512         test_mkdir $DIR/d29
3513         touch $DIR/d29/foo
3514         log 'first d29'
3515         ls -l $DIR/d29
3516
3517         declare -i LOCKCOUNTORIG=0
3518         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3519                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3520         done
3521         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3522
3523         declare -i LOCKUNUSEDCOUNTORIG=0
3524         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3525                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3526         done
3527
3528         log 'second d29'
3529         ls -l $DIR/d29
3530         log 'done'
3531
3532         declare -i LOCKCOUNTCURRENT=0
3533         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3534                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3535         done
3536
3537         declare -i LOCKUNUSEDCOUNTCURRENT=0
3538         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3539                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3540         done
3541
3542         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3543                 $LCTL set_param -n ldlm.dump_namespaces ""
3544                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3545                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3546                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3547                 return 2
3548         fi
3549         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3550                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3551                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3552                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3553                 return 3
3554         fi
3555 }
3556 run_test 29 "IT_GETATTR regression  ============================"
3557
3558 test_30a() { # was test_30
3559         cp $(which ls) $DIR || cp /bin/ls $DIR
3560         $DIR/ls / || error "Can't execute binary from lustre"
3561         rm $DIR/ls
3562 }
3563 run_test 30a "execute binary from Lustre (execve) =============="
3564
3565 test_30b() {
3566         cp `which ls` $DIR || cp /bin/ls $DIR
3567         chmod go+rx $DIR/ls
3568         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3569         rm $DIR/ls
3570 }
3571 run_test 30b "execute binary from Lustre as non-root ==========="
3572
3573 test_30c() { # b=22376
3574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3575
3576         cp $(which ls) $DIR || cp /bin/ls $DIR
3577         chmod a-rw $DIR/ls
3578         cancel_lru_locks mdc
3579         cancel_lru_locks osc
3580         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3581         rm -f $DIR/ls
3582 }
3583 run_test 30c "execute binary from Lustre without read perms ===="
3584
3585 test_30d() {
3586         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3587
3588         for i in {1..10}; do
3589                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3590                 local PID=$!
3591                 sleep 1
3592                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3593                 wait $PID || error "executing dd from Lustre failed"
3594                 rm -f $DIR/$tfile
3595         done
3596
3597         rm -f $DIR/dd
3598 }
3599 run_test 30d "execute binary from Lustre while clear locks"
3600
3601 test_31a() {
3602         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3603         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3604 }
3605 run_test 31a "open-unlink file =================================="
3606
3607 test_31b() {
3608         touch $DIR/f31 || error "touch $DIR/f31 failed"
3609         ln $DIR/f31 $DIR/f31b || error "ln failed"
3610         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3611         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3612 }
3613 run_test 31b "unlink file with multiple links while open ======="
3614
3615 test_31c() {
3616         touch $DIR/f31 || error "touch $DIR/f31 failed"
3617         ln $DIR/f31 $DIR/f31c || error "ln failed"
3618         multiop_bg_pause $DIR/f31 O_uc ||
3619                 error "multiop_bg_pause for $DIR/f31 failed"
3620         MULTIPID=$!
3621         $MULTIOP $DIR/f31c Ouc
3622         kill -USR1 $MULTIPID
3623         wait $MULTIPID
3624 }
3625 run_test 31c "open-unlink file with multiple links ============="
3626
3627 test_31d() {
3628         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3629         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3630 }
3631 run_test 31d "remove of open directory ========================="
3632
3633 test_31e() { # bug 2904
3634         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3635 }
3636 run_test 31e "remove of open non-empty directory ==============="
3637
3638 test_31f() { # bug 4554
3639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3640
3641         set -vx
3642         test_mkdir $DIR/d31f
3643         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3644         cp /etc/hosts $DIR/d31f
3645         ls -l $DIR/d31f
3646         $LFS getstripe $DIR/d31f/hosts
3647         multiop_bg_pause $DIR/d31f D_c || return 1
3648         MULTIPID=$!
3649
3650         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3651         test_mkdir $DIR/d31f
3652         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3653         cp /etc/hosts $DIR/d31f
3654         ls -l $DIR/d31f
3655         $LFS getstripe $DIR/d31f/hosts
3656         multiop_bg_pause $DIR/d31f D_c || return 1
3657         MULTIPID2=$!
3658
3659         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3660         wait $MULTIPID || error "first opendir $MULTIPID failed"
3661
3662         sleep 6
3663
3664         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3665         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3666         set +vx
3667 }
3668 run_test 31f "remove of open directory with open-unlink file ==="
3669
3670 test_31g() {
3671         echo "-- cross directory link --"
3672         test_mkdir -c1 $DIR/${tdir}ga
3673         test_mkdir -c1 $DIR/${tdir}gb
3674         touch $DIR/${tdir}ga/f
3675         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3676         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3677         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3678         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3679         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3680 }
3681 run_test 31g "cross directory link==============="
3682
3683 test_31h() {
3684         echo "-- cross directory link --"
3685         test_mkdir -c1 $DIR/${tdir}
3686         test_mkdir -c1 $DIR/${tdir}/dir
3687         touch $DIR/${tdir}/f
3688         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3689         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3690         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3691         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3692         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3693 }
3694 run_test 31h "cross directory link under child==============="
3695
3696 test_31i() {
3697         echo "-- cross directory link --"
3698         test_mkdir -c1 $DIR/$tdir
3699         test_mkdir -c1 $DIR/$tdir/dir
3700         touch $DIR/$tdir/dir/f
3701         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3702         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3703         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3704         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3705         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3706 }
3707 run_test 31i "cross directory link under parent==============="
3708
3709 test_31j() {
3710         test_mkdir -c1 -p $DIR/$tdir
3711         test_mkdir -c1 -p $DIR/$tdir/dir1
3712         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3713         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3714         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3715         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3716         return 0
3717 }
3718 run_test 31j "link for directory==============="
3719
3720 test_31k() {
3721         test_mkdir -c1 -p $DIR/$tdir
3722         touch $DIR/$tdir/s
3723         touch $DIR/$tdir/exist
3724         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3725         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3726         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3727         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3728         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3729         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3730         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3731         return 0
3732 }
3733 run_test 31k "link to file: the same, non-existing, dir==============="
3734
3735 test_31l() {
3736         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3737
3738         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3739         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3740                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3741
3742         touch $DIR/$tfile || error "create failed"
3743         mkdir $DIR/$tdir || error "mkdir failed"
3744         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3745 }
3746 run_test 31l "link to file: target dir has trailing slash"
3747
3748 test_31m() {
3749         mkdir $DIR/d31m
3750         touch $DIR/d31m/s
3751         mkdir $DIR/d31m2
3752         touch $DIR/d31m2/exist
3753         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3754         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3755         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3756         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3757         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3758         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3759         return 0
3760 }
3761 run_test 31m "link to file: the same, non-existing, dir==============="
3762
3763 test_31n() {
3764         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3765         nlink=$(stat --format=%h $DIR/$tfile)
3766         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3767         local fd=$(free_fd)
3768         local cmd="exec $fd<$DIR/$tfile"
3769         eval $cmd
3770         cmd="exec $fd<&-"
3771         trap "eval $cmd" EXIT
3772         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3773         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3774         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3775         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3776         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3777         eval $cmd
3778 }
3779 run_test 31n "check link count of unlinked file"
3780
3781 link_one() {
3782         local tempfile=$(mktemp $1_XXXXXX)
3783         mlink $tempfile $1 2> /dev/null &&
3784                 echo "$BASHPID: link $tempfile to $1 succeeded"
3785         munlink $tempfile
3786 }
3787
3788 test_31o() { # LU-2901
3789         test_mkdir $DIR/$tdir
3790         for LOOP in $(seq 100); do
3791                 rm -f $DIR/$tdir/$tfile*
3792                 for THREAD in $(seq 8); do
3793                         link_one $DIR/$tdir/$tfile.$LOOP &
3794                 done
3795                 wait
3796                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3797                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3798                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3799                         break || true
3800         done
3801 }
3802 run_test 31o "duplicate hard links with same filename"
3803
3804 test_31p() {
3805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3806
3807         test_mkdir $DIR/$tdir
3808         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3809         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3810
3811         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3812                 error "open unlink test1 failed"
3813         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3814                 error "open unlink test2 failed"
3815
3816         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3817                 error "test1 still exists"
3818         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3819                 error "test2 still exists"
3820 }
3821 run_test 31p "remove of open striped directory"
3822
3823 test_31q() {
3824         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3825
3826         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3827         index=$($LFS getdirstripe -i $DIR/$tdir)
3828         [ $index -eq 3 ] || error "first stripe index $index != 3"
3829         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3830         [ $index -eq 1 ] || error "second stripe index $index != 1"
3831
3832         # when "-c <stripe_count>" is set, the number of MDTs specified after
3833         # "-i" should equal to the stripe count
3834         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3835 }
3836 run_test 31q "create striped directory on specific MDTs"
3837
3838 #LU-14949
3839 test_31r() {
3840         touch $DIR/$tfile.target
3841         touch $DIR/$tfile.source
3842
3843         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3844         $LCTL set_param fail_loc=0x1419 fail_val=3
3845         cat $DIR/$tfile.target &
3846         CATPID=$!
3847
3848         # Guarantee open is waiting before we get here
3849         sleep 1
3850         mv $DIR/$tfile.source $DIR/$tfile.target
3851
3852         wait $CATPID
3853         RC=$?
3854         if [[ $RC -ne 0 ]]; then
3855                 error "open with cat failed, rc=$RC"
3856         fi
3857 }
3858 run_test 31r "open-rename(replace) race"
3859
3860 cleanup_test32_mount() {
3861         local rc=0
3862         trap 0
3863         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3864         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3865         losetup -d $loopdev || true
3866         rm -rf $DIR/$tdir
3867         return $rc
3868 }
3869
3870 test_32a() {
3871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3872
3873         echo "== more mountpoints and symlinks ================="
3874         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3875         trap cleanup_test32_mount EXIT
3876         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3877         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3878                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3879         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3880                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3881         cleanup_test32_mount
3882 }
3883 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3884
3885 test_32b() {
3886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3887
3888         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3889         trap cleanup_test32_mount EXIT
3890         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3893         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3894                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3895         cleanup_test32_mount
3896 }
3897 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3898
3899 test_32c() {
3900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3901
3902         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3903         trap cleanup_test32_mount EXIT
3904         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3905         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3906                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3907         test_mkdir -p $DIR/$tdir/d2/test_dir
3908         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3909                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3910         cleanup_test32_mount
3911 }
3912 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3913
3914 test_32d() {
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3918         trap cleanup_test32_mount EXIT
3919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3920         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3921                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3922         test_mkdir -p $DIR/$tdir/d2/test_dir
3923         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3924                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3925         cleanup_test32_mount
3926 }
3927 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3928
3929 test_32e() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir -p $DIR/$tdir/tmp
3932         local tmp_dir=$DIR/$tdir/tmp
3933         ln -s $DIR/$tdir $tmp_dir/symlink11
3934         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3935         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3936         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3937 }
3938 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3939
3940 test_32f() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir -p $DIR/$tdir/tmp
3943         local tmp_dir=$DIR/$tdir/tmp
3944         ln -s $DIR/$tdir $tmp_dir/symlink11
3945         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3946         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3947         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3948 }
3949 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3950
3951 test_32g() {
3952         local tmp_dir=$DIR/$tdir/tmp
3953         test_mkdir -p $tmp_dir
3954         test_mkdir $DIR/${tdir}2
3955         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3956         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3957         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3958         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3959         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3960         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3961 }
3962 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3963
3964 test_32h() {
3965         rm -fr $DIR/$tdir $DIR/${tdir}2
3966         tmp_dir=$DIR/$tdir/tmp
3967         test_mkdir -p $tmp_dir
3968         test_mkdir $DIR/${tdir}2
3969         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3970         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3971         ls $tmp_dir/symlink12 || error "listing symlink12"
3972         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3973 }
3974 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3975
3976 test_32i() {
3977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3978
3979         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3980         trap cleanup_test32_mount EXIT
3981         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3982         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3983                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3984         touch $DIR/$tdir/test_file
3985         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3986                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3987         cleanup_test32_mount
3988 }
3989 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3990
3991 test_32j() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3995         trap cleanup_test32_mount EXIT
3996         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3997         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3998                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3999         touch $DIR/$tdir/test_file
4000         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4001                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4002         cleanup_test32_mount
4003 }
4004 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4005
4006 test_32k() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         test_mkdir -p $DIR/$tdir/d2
4015         touch $DIR/$tdir/d2/test_file || error "touch failed"
4016         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4017                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4018         cleanup_test32_mount
4019 }
4020 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4021
4022 test_32l() {
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024
4025         rm -fr $DIR/$tdir
4026         trap cleanup_test32_mount EXIT
4027         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4028         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4029                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4030         test_mkdir -p $DIR/$tdir/d2
4031         touch $DIR/$tdir/d2/test_file || error "touch failed"
4032         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4033                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4034         cleanup_test32_mount
4035 }
4036 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4037
4038 test_32m() {
4039         rm -fr $DIR/d32m
4040         test_mkdir -p $DIR/d32m/tmp
4041         TMP_DIR=$DIR/d32m/tmp
4042         ln -s $DIR $TMP_DIR/symlink11
4043         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4044         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4045                 error "symlink11 not a link"
4046         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4047                 error "symlink01 not a link"
4048 }
4049 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4050
4051 test_32n() {
4052         rm -fr $DIR/d32n
4053         test_mkdir -p $DIR/d32n/tmp
4054         TMP_DIR=$DIR/d32n/tmp
4055         ln -s $DIR $TMP_DIR/symlink11
4056         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4057         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4058         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4059 }
4060 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4061
4062 test_32o() {
4063         touch $DIR/$tfile
4064         test_mkdir -p $DIR/d32o/tmp
4065         TMP_DIR=$DIR/d32o/tmp
4066         ln -s $DIR/$tfile $TMP_DIR/symlink12
4067         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4068         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4069                 error "symlink12 not a link"
4070         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4071         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4072                 error "$DIR/d32o/tmp/symlink12 not file type"
4073         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4074                 error "$DIR/d32o/symlink02 not file type"
4075 }
4076 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4077
4078 test_32p() {
4079         log 32p_1
4080         rm -fr $DIR/d32p
4081         log 32p_2
4082         rm -f $DIR/$tfile
4083         log 32p_3
4084         touch $DIR/$tfile
4085         log 32p_4
4086         test_mkdir -p $DIR/d32p/tmp
4087         log 32p_5
4088         TMP_DIR=$DIR/d32p/tmp
4089         log 32p_6
4090         ln -s $DIR/$tfile $TMP_DIR/symlink12
4091         log 32p_7
4092         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4093         log 32p_8
4094         cat $DIR/d32p/tmp/symlink12 ||
4095                 error "Can't open $DIR/d32p/tmp/symlink12"
4096         log 32p_9
4097         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4098         log 32p_10
4099 }
4100 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4101
4102 test_32q() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104
4105         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4106         trap cleanup_test32_mount EXIT
4107         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4108         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4109         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4110                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4111         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4112         cleanup_test32_mount
4113 }
4114 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4115
4116 test_32r() {
4117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4118
4119         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4120         trap cleanup_test32_mount EXIT
4121         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4122         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4123         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4124                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4125         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4126         cleanup_test32_mount
4127 }
4128 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4129
4130 test_33aa() {
4131         rm -f $DIR/$tfile
4132         touch $DIR/$tfile
4133         chmod 444 $DIR/$tfile
4134         chown $RUNAS_ID $DIR/$tfile
4135         log 33_1
4136         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4137         log 33_2
4138 }
4139 run_test 33aa "write file with mode 444 (should return error)"
4140
4141 test_33a() {
4142         rm -fr $DIR/$tdir
4143         test_mkdir $DIR/$tdir
4144         chown $RUNAS_ID $DIR/$tdir
4145         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4146                 error "$RUNAS create $tdir/$tfile failed"
4147         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4148                 error "open RDWR" || true
4149 }
4150 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4151
4152 test_33b() {
4153         rm -fr $DIR/$tdir
4154         test_mkdir $DIR/$tdir
4155         chown $RUNAS_ID $DIR/$tdir
4156         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4157 }
4158 run_test 33b "test open file with malformed flags (No panic)"
4159
4160 test_33c() {
4161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4162         remote_ost_nodsh && skip "remote OST with nodsh"
4163
4164         local ostnum
4165         local ostname
4166         local write_bytes
4167         local all_zeros
4168
4169         all_zeros=true
4170         test_mkdir $DIR/$tdir
4171         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4172
4173         sync
4174         for ostnum in $(seq $OSTCOUNT); do
4175                 # test-framework's OST numbering is one-based, while Lustre's
4176                 # is zero-based
4177                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4178                 # check if at least some write_bytes stats are counted
4179                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4180                               obdfilter.$ostname.stats |
4181                               awk '/^write_bytes/ {print $7}' )
4182                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4183                 if (( ${write_bytes:-0} > 0 )); then
4184                         all_zeros=false
4185                         break
4186                 fi
4187         done
4188
4189         $all_zeros || return 0
4190
4191         # Write four bytes
4192         echo foo > $DIR/$tdir/bar
4193         # Really write them
4194         sync
4195
4196         # Total up write_bytes after writing.  We'd better find non-zeros.
4197         for ostnum in $(seq $OSTCOUNT); do
4198                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4199                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4200                               obdfilter/$ostname/stats |
4201                               awk '/^write_bytes/ {print $7}' )
4202                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4203                 if (( ${write_bytes:-0} > 0 )); then
4204                         all_zeros=false
4205                         break
4206                 fi
4207         done
4208
4209         if $all_zeros; then
4210                 for ostnum in $(seq $OSTCOUNT); do
4211                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                         echo "Check write_bytes is in obdfilter.*.stats:"
4213                         do_facet ost$ostnum lctl get_param -n \
4214                                 obdfilter.$ostname.stats
4215                 done
4216                 error "OST not keeping write_bytes stats (b=22312)"
4217         fi
4218 }
4219 run_test 33c "test write_bytes stats"
4220
4221 test_33d() {
4222         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4224
4225         local MDTIDX=1
4226         local remote_dir=$DIR/$tdir/remote_dir
4227
4228         test_mkdir $DIR/$tdir
4229         $LFS mkdir -i $MDTIDX $remote_dir ||
4230                 error "create remote directory failed"
4231
4232         touch $remote_dir/$tfile
4233         chmod 444 $remote_dir/$tfile
4234         chown $RUNAS_ID $remote_dir/$tfile
4235
4236         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4237
4238         chown $RUNAS_ID $remote_dir
4239         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4240                                         error "create" || true
4241         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4242                                     error "open RDWR" || true
4243         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4244 }
4245 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4246
4247 test_33e() {
4248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4249
4250         mkdir $DIR/$tdir
4251
4252         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4253         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4254         mkdir $DIR/$tdir/local_dir
4255
4256         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4257         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4258         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4259
4260         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4261                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4262
4263         rmdir $DIR/$tdir/* || error "rmdir failed"
4264
4265         umask 777
4266         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4267         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4268         mkdir $DIR/$tdir/local_dir
4269
4270         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4271         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4272         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4273
4274         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4275                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4276
4277         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4278
4279         umask 000
4280         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4281         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4282         mkdir $DIR/$tdir/local_dir
4283
4284         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4285         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4286         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4287
4288         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4289                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4290 }
4291 run_test 33e "mkdir and striped directory should have same mode"
4292
4293 cleanup_33f() {
4294         trap 0
4295         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4296 }
4297
4298 test_33f() {
4299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4300         remote_mds_nodsh && skip "remote MDS with nodsh"
4301
4302         mkdir $DIR/$tdir
4303         chmod go+rwx $DIR/$tdir
4304         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4305         trap cleanup_33f EXIT
4306
4307         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4308                 error "cannot create striped directory"
4309
4310         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4311                 error "cannot create files in striped directory"
4312
4313         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4314                 error "cannot remove files in striped directory"
4315
4316         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4317                 error "cannot remove striped directory"
4318
4319         cleanup_33f
4320 }
4321 run_test 33f "nonroot user can create, access, and remove a striped directory"
4322
4323 test_33g() {
4324         mkdir -p $DIR/$tdir/dir2
4325
4326         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4327         echo $err
4328         [[ $err =~ "exists" ]] || error "Not exists error"
4329 }
4330 run_test 33g "nonroot user create already existing root created file"
4331
4332 sub_33h() {
4333         local hash_type=$1
4334         local count=250
4335
4336         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4337                 error "lfs mkdir -H $hash_type $tdir failed"
4338         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4339
4340         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4341         local index2
4342         local fname
4343
4344         for fname in $DIR/$tdir/$tfile.bak \
4345                      $DIR/$tdir/$tfile.SAV \
4346                      $DIR/$tdir/$tfile.orig \
4347                      $DIR/$tdir/$tfile~; do
4348                 touch $fname || error "touch $fname failed"
4349                 index2=$($LFS getstripe -m $fname)
4350                 (( $index == $index2 )) ||
4351                         error "$fname MDT index mismatch $index != $index2"
4352         done
4353
4354         local failed=0
4355         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4356         local pattern
4357
4358         for pattern in ${patterns[*]}; do
4359                 echo "pattern $pattern"
4360                 fname=$DIR/$tdir/$pattern
4361                 for (( i = 0; i < $count; i++ )); do
4362                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4363                                 error "mktemp $DIR/$tdir/$pattern failed"
4364                         index2=$($LFS getstripe -m $fname)
4365                         (( $index == $index2 )) && continue
4366
4367                         failed=$((failed + 1))
4368                         echo "$fname MDT index mismatch $index != $index2"
4369                 done
4370         done
4371
4372         echo "$failed/$count MDT index mismatches, expect ~2-4"
4373         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4374
4375         local same=0
4376         local expect
4377
4378         # verify that "crush" is still broken with all files on same MDT,
4379         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4380         [[ "$hash_type" == "crush" ]] && expect=$count ||
4381                 expect=$((count / MDSCOUNT))
4382
4383         # crush2 doesn't put all-numeric suffixes on the same MDT,
4384         # filename like $tfile.12345678 should *not* be considered temp
4385         for pattern in ${patterns[*]}; do
4386                 local base=${pattern%%X*}
4387                 local suff=${pattern#$base}
4388
4389                 echo "pattern $pattern"
4390                 for (( i = 0; i < $count; i++ )); do
4391                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4392                         touch $fname || error "touch $fname failed"
4393                         index2=$($LFS getstripe -m $fname)
4394                         (( $index != $index2 )) && continue
4395
4396                         same=$((same + 1))
4397                 done
4398         done
4399
4400         # the number of "bad" hashes is random, as it depends on the random
4401         # filenames generated by "mktemp".  Allow some margin in the results.
4402         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4403         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4404            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4405                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4406         same=0
4407
4408         # crush2 doesn't put suffixes with special characters on the same MDT
4409         # filename like $tfile.txt.1234 should *not* be considered temp
4410         for pattern in ${patterns[*]}; do
4411                 local base=${pattern%%X*}
4412                 local suff=${pattern#$base}
4413
4414                 pattern=$base...${suff/XXX}
4415                 echo "pattern=$pattern"
4416                 for (( i = 0; i < $count; i++ )); do
4417                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4418                                 error "touch $fname failed"
4419                         index2=$($LFS getstripe -m $fname)
4420                         (( $index != $index2 )) && continue
4421
4422                         same=$((same + 1))
4423                 done
4424         done
4425
4426         # the number of "bad" hashes is random, as it depends on the random
4427         # filenames generated by "mktemp".  Allow some margin in the results.
4428         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4429         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4430            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4431                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4432 }
4433
4434 test_33h() {
4435         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4436         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4437                 skip "Need MDS version at least 2.13.50"
4438
4439         sub_33h crush
4440 }
4441 run_test 33h "temp file is located on the same MDT as target (crush)"
4442
4443 test_33hh() {
4444         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4445         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4446         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4447                 skip "Need MDS version at least 2.15.0 for crush2"
4448
4449         sub_33h crush2
4450 }
4451 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4452
4453 test_33i()
4454 {
4455         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4456
4457         local FNAME=$(str_repeat 'f' 250)
4458
4459         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4460         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4461
4462         local count
4463         local total
4464
4465         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4466
4467         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4468
4469         lctl --device %$MDC deactivate
4470         stack_trap "lctl --device %$MDC activate"
4471         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4472         total=$(\ls -l $DIR/$tdir | wc -l)
4473         # "ls -l" will list total in the first line
4474         total=$((total - 1))
4475         (( total + count == 1000 )) ||
4476                 error "ls list $total files, $count files on MDT1"
4477 }
4478 run_test 33i "striped directory can be accessed when one MDT is down"
4479
4480 test_33j() {
4481         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4482
4483         mkdir -p $DIR/$tdir/
4484
4485         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4486                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4487
4488         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4489                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4490
4491         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4492                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4493
4494         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4495                 error "-D was not specified, but still failed"
4496 }
4497 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4498
4499 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4500 test_34a() {
4501         rm -f $DIR/f34
4502         $MCREATE $DIR/f34 || error "mcreate failed"
4503         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4504                 error "getstripe failed"
4505         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4506         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4507                 error "getstripe failed"
4508         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4509                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4510 }
4511 run_test 34a "truncate file that has not been opened ==========="
4512
4513 test_34b() {
4514         [ ! -f $DIR/f34 ] && test_34a
4515         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4516                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4517         $OPENFILE -f O_RDONLY $DIR/f34
4518         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4519                 error "getstripe failed"
4520         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4521                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4522 }
4523 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4524
4525 test_34c() {
4526         [ ! -f $DIR/f34 ] && test_34a
4527         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4528                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4529         $OPENFILE -f O_RDWR $DIR/f34
4530         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4531                 error "$LFS getstripe failed"
4532         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4533                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4534 }
4535 run_test 34c "O_RDWR opening file-with-size works =============="
4536
4537 test_34d() {
4538         [ ! -f $DIR/f34 ] && test_34a
4539         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4540                 error "dd failed"
4541         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4542                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4543         rm $DIR/f34
4544 }
4545 run_test 34d "write to sparse file ============================="
4546
4547 test_34e() {
4548         rm -f $DIR/f34e
4549         $MCREATE $DIR/f34e || error "mcreate failed"
4550         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4551         $CHECKSTAT -s 1000 $DIR/f34e ||
4552                 error "Size of $DIR/f34e not equal to 1000 bytes"
4553         $OPENFILE -f O_RDWR $DIR/f34e
4554         $CHECKSTAT -s 1000 $DIR/f34e ||
4555                 error "Size of $DIR/f34e not equal to 1000 bytes"
4556 }
4557 run_test 34e "create objects, some with size and some without =="
4558
4559 test_34f() { # bug 6242, 6243
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         SIZE34F=48000
4563         rm -f $DIR/f34f
4564         $MCREATE $DIR/f34f || error "mcreate failed"
4565         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4566         dd if=$DIR/f34f of=$TMP/f34f
4567         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4568         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4569         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4570         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4571         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4572 }
4573 run_test 34f "read from a file with no objects until EOF ======="
4574
4575 test_34g() {
4576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4577
4578         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4579                 error "dd failed"
4580         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4581         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4582                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4583         cancel_lru_locks osc
4584         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4585                 error "wrong size after lock cancel"
4586
4587         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4588         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4589                 error "expanding truncate failed"
4590         cancel_lru_locks osc
4591         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4592                 error "wrong expanded size after lock cancel"
4593 }
4594 run_test 34g "truncate long file ==============================="
4595
4596 test_34h() {
4597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4598
4599         local gid=10
4600         local sz=1000
4601
4602         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4603         sync # Flush the cache so that multiop below does not block on cache
4604              # flush when getting the group lock
4605         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4606         MULTIPID=$!
4607
4608         # Since just timed wait is not good enough, let's do a sync write
4609         # that way we are sure enough time for a roundtrip + processing
4610         # passed + 2 seconds of extra margin.
4611         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4612         rm $DIR/${tfile}-1
4613         sleep 2
4614
4615         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4616                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4617                 kill -9 $MULTIPID
4618         fi
4619         wait $MULTIPID
4620         local nsz=`stat -c %s $DIR/$tfile`
4621         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4622 }
4623 run_test 34h "ftruncate file under grouplock should not block"
4624
4625 test_35a() {
4626         cp /bin/sh $DIR/f35a
4627         chmod 444 $DIR/f35a
4628         chown $RUNAS_ID $DIR/f35a
4629         $RUNAS $DIR/f35a && error || true
4630         rm $DIR/f35a
4631 }
4632 run_test 35a "exec file with mode 444 (should return and not leak)"
4633
4634 test_36a() {
4635         rm -f $DIR/f36
4636         utime $DIR/f36 || error "utime failed for MDS"
4637 }
4638 run_test 36a "MDS utime check (mknod, utime)"
4639
4640 test_36b() {
4641         echo "" > $DIR/f36
4642         utime $DIR/f36 || error "utime failed for OST"
4643 }
4644 run_test 36b "OST utime check (open, utime)"
4645
4646 test_36c() {
4647         rm -f $DIR/d36/f36
4648         test_mkdir $DIR/d36
4649         chown $RUNAS_ID $DIR/d36
4650         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4651 }
4652 run_test 36c "non-root MDS utime check (mknod, utime)"
4653
4654 test_36d() {
4655         [ ! -d $DIR/d36 ] && test_36c
4656         echo "" > $DIR/d36/f36
4657         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4658 }
4659 run_test 36d "non-root OST utime check (open, utime)"
4660
4661 test_36e() {
4662         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4663
4664         test_mkdir $DIR/$tdir
4665         touch $DIR/$tdir/$tfile
4666         $RUNAS utime $DIR/$tdir/$tfile &&
4667                 error "utime worked, expected failure" || true
4668 }
4669 run_test 36e "utime on non-owned file (should return error)"
4670
4671 subr_36fh() {
4672         local fl="$1"
4673         local LANG_SAVE=$LANG
4674         local LC_LANG_SAVE=$LC_LANG
4675         export LANG=C LC_LANG=C # for date language
4676
4677         DATESTR="Dec 20  2000"
4678         test_mkdir $DIR/$tdir
4679         lctl set_param fail_loc=$fl
4680         date; date +%s
4681         cp /etc/hosts $DIR/$tdir/$tfile
4682         sync & # write RPC generated with "current" inode timestamp, but delayed
4683         sleep 1
4684         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4685         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4686         cancel_lru_locks $OSC
4687         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4688         date; date +%s
4689         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4690                 echo "BEFORE: $LS_BEFORE" && \
4691                 echo "AFTER : $LS_AFTER" && \
4692                 echo "WANT  : $DATESTR" && \
4693                 error "$DIR/$tdir/$tfile timestamps changed" || true
4694
4695         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4696 }
4697
4698 test_36f() {
4699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4700
4701         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4702         subr_36fh "0x80000214"
4703 }
4704 run_test 36f "utime on file racing with OST BRW write =========="
4705
4706 test_36g() {
4707         remote_ost_nodsh && skip "remote OST with nodsh"
4708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4709         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4710                 skip "Need MDS version at least 2.12.51"
4711
4712         local fmd_max_age
4713         local fmd
4714         local facet="ost1"
4715         local tgt="obdfilter"
4716
4717         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4718
4719         test_mkdir $DIR/$tdir
4720         fmd_max_age=$(do_facet $facet \
4721                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4722                 head -n 1")
4723
4724         echo "FMD max age: ${fmd_max_age}s"
4725         touch $DIR/$tdir/$tfile
4726         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4727                 gawk '{cnt=cnt+$1}  END{print cnt}')
4728         echo "FMD before: $fmd"
4729         [[ $fmd == 0 ]] &&
4730                 error "FMD wasn't create by touch"
4731         sleep $((fmd_max_age + 12))
4732         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4733                 gawk '{cnt=cnt+$1}  END{print cnt}')
4734         echo "FMD after: $fmd"
4735         [[ $fmd == 0 ]] ||
4736                 error "FMD wasn't expired by ping"
4737 }
4738 run_test 36g "FMD cache expiry ====================="
4739
4740 test_36h() {
4741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4742
4743         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4744         subr_36fh "0x80000227"
4745 }
4746 run_test 36h "utime on file racing with OST BRW write =========="
4747
4748 test_36i() {
4749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4750
4751         test_mkdir $DIR/$tdir
4752         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4753
4754         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4755         local new_mtime=$((mtime + 200))
4756
4757         #change Modify time of striped dir
4758         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4759                         error "change mtime failed"
4760
4761         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4762
4763         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4764 }
4765 run_test 36i "change mtime on striped directory"
4766
4767 # test_37 - duplicate with tests 32q 32r
4768
4769 test_38() {
4770         local file=$DIR/$tfile
4771         touch $file
4772         openfile -f O_DIRECTORY $file
4773         local RC=$?
4774         local ENOTDIR=20
4775         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4776         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4777 }
4778 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4779
4780 test_39a() { # was test_39
4781         touch $DIR/$tfile
4782         touch $DIR/${tfile}2
4783 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4784 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4785 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4786         sleep 2
4787         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4788         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4789                 echo "mtime"
4790                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4791                 echo "atime"
4792                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4793                 echo "ctime"
4794                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4795                 error "O_TRUNC didn't change timestamps"
4796         fi
4797 }
4798 run_test 39a "mtime changed on create"
4799
4800 test_39b() {
4801         test_mkdir -c1 $DIR/$tdir
4802         cp -p /etc/passwd $DIR/$tdir/fopen
4803         cp -p /etc/passwd $DIR/$tdir/flink
4804         cp -p /etc/passwd $DIR/$tdir/funlink
4805         cp -p /etc/passwd $DIR/$tdir/frename
4806         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4807
4808         sleep 1
4809         echo "aaaaaa" >> $DIR/$tdir/fopen
4810         echo "aaaaaa" >> $DIR/$tdir/flink
4811         echo "aaaaaa" >> $DIR/$tdir/funlink
4812         echo "aaaaaa" >> $DIR/$tdir/frename
4813
4814         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4815         local link_new=`stat -c %Y $DIR/$tdir/flink`
4816         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4817         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4818
4819         cat $DIR/$tdir/fopen > /dev/null
4820         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4821         rm -f $DIR/$tdir/funlink2
4822         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4826                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4827                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4828                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4829
4830                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4831                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4832                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4833                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4834
4835                 cancel_lru_locks $OSC
4836                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4837         done
4838 }
4839 run_test 39b "mtime change on open, link, unlink, rename  ======"
4840
4841 # this should be set to past
4842 TEST_39_MTIME=`date -d "1 year ago" +%s`
4843
4844 # bug 11063
4845 test_39c() {
4846         touch $DIR1/$tfile
4847         sleep 2
4848         local mtime0=`stat -c %Y $DIR1/$tfile`
4849
4850         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4851         local mtime1=`stat -c %Y $DIR1/$tfile`
4852         [ "$mtime1" = $TEST_39_MTIME ] || \
4853                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4854
4855         local d1=`date +%s`
4856         echo hello >> $DIR1/$tfile
4857         local d2=`date +%s`
4858         local mtime2=`stat -c %Y $DIR1/$tfile`
4859         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4860                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4861
4862         mv $DIR1/$tfile $DIR1/$tfile-1
4863
4864         for (( i=0; i < 2; i++ )) ; do
4865                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4866                 [ "$mtime2" = "$mtime3" ] || \
4867                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4868
4869                 cancel_lru_locks $OSC
4870                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4871         done
4872 }
4873 run_test 39c "mtime change on rename ==========================="
4874
4875 # bug 21114
4876 test_39d() {
4877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4878
4879         touch $DIR1/$tfile
4880         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4881
4882         for (( i=0; i < 2; i++ )) ; do
4883                 local mtime=`stat -c %Y $DIR1/$tfile`
4884                 [ $mtime = $TEST_39_MTIME ] || \
4885                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4886
4887                 cancel_lru_locks $OSC
4888                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4889         done
4890 }
4891 run_test 39d "create, utime, stat =============================="
4892
4893 # bug 21114
4894 test_39e() {
4895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4896
4897         touch $DIR1/$tfile
4898         local mtime1=`stat -c %Y $DIR1/$tfile`
4899
4900         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4901
4902         for (( i=0; i < 2; i++ )) ; do
4903                 local mtime2=`stat -c %Y $DIR1/$tfile`
4904                 [ $mtime2 = $TEST_39_MTIME ] || \
4905                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4906
4907                 cancel_lru_locks $OSC
4908                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4909         done
4910 }
4911 run_test 39e "create, stat, utime, stat ========================"
4912
4913 # bug 21114
4914 test_39f() {
4915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4916
4917         touch $DIR1/$tfile
4918         mtime1=`stat -c %Y $DIR1/$tfile`
4919
4920         sleep 2
4921         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4922
4923         for (( i=0; i < 2; i++ )) ; do
4924                 local mtime2=`stat -c %Y $DIR1/$tfile`
4925                 [ $mtime2 = $TEST_39_MTIME ] || \
4926                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4927
4928                 cancel_lru_locks $OSC
4929                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4930         done
4931 }
4932 run_test 39f "create, stat, sleep, utime, stat ================="
4933
4934 # bug 11063
4935 test_39g() {
4936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4937
4938         echo hello >> $DIR1/$tfile
4939         local mtime1=`stat -c %Y $DIR1/$tfile`
4940
4941         sleep 2
4942         chmod o+r $DIR1/$tfile
4943
4944         for (( i=0; i < 2; i++ )) ; do
4945                 local mtime2=`stat -c %Y $DIR1/$tfile`
4946                 [ "$mtime1" = "$mtime2" ] || \
4947                         error "lost mtime: $mtime2, should be $mtime1"
4948
4949                 cancel_lru_locks $OSC
4950                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4951         done
4952 }
4953 run_test 39g "write, chmod, stat ==============================="
4954
4955 # bug 11063
4956 test_39h() {
4957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4958
4959         touch $DIR1/$tfile
4960         sleep 1
4961
4962         local d1=`date`
4963         echo hello >> $DIR1/$tfile
4964         local mtime1=`stat -c %Y $DIR1/$tfile`
4965
4966         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4967         local d2=`date`
4968         if [ "$d1" != "$d2" ]; then
4969                 echo "write and touch not within one second"
4970         else
4971                 for (( i=0; i < 2; i++ )) ; do
4972                         local mtime2=`stat -c %Y $DIR1/$tfile`
4973                         [ "$mtime2" = $TEST_39_MTIME ] || \
4974                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4975
4976                         cancel_lru_locks $OSC
4977                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4978                 done
4979         fi
4980 }
4981 run_test 39h "write, utime within one second, stat ============="
4982
4983 test_39i() {
4984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4985
4986         touch $DIR1/$tfile
4987         sleep 1
4988
4989         echo hello >> $DIR1/$tfile
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         mv $DIR1/$tfile $DIR1/$tfile-1
4993
4994         for (( i=0; i < 2; i++ )) ; do
4995                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4996
4997                 [ "$mtime1" = "$mtime2" ] || \
4998                         error "lost mtime: $mtime2, should be $mtime1"
4999
5000                 cancel_lru_locks $OSC
5001                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5002         done
5003 }
5004 run_test 39i "write, rename, stat =============================="
5005
5006 test_39j() {
5007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5008
5009         start_full_debug_logging
5010         touch $DIR1/$tfile
5011         sleep 1
5012
5013         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5014         lctl set_param fail_loc=0x80000412
5015         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5016                 error "multiop failed"
5017         local multipid=$!
5018         local mtime1=`stat -c %Y $DIR1/$tfile`
5019
5020         mv $DIR1/$tfile $DIR1/$tfile-1
5021
5022         kill -USR1 $multipid
5023         wait $multipid || error "multiop close failed"
5024
5025         for (( i=0; i < 2; i++ )) ; do
5026                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5027                 [ "$mtime1" = "$mtime2" ] ||
5028                         error "mtime is lost on close: $mtime2, " \
5029                               "should be $mtime1"
5030
5031                 cancel_lru_locks
5032                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5033         done
5034         lctl set_param fail_loc=0
5035         stop_full_debug_logging
5036 }
5037 run_test 39j "write, rename, close, stat ======================="
5038
5039 test_39k() {
5040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5041
5042         touch $DIR1/$tfile
5043         sleep 1
5044
5045         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5046         local multipid=$!
5047         local mtime1=`stat -c %Y $DIR1/$tfile`
5048
5049         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5050
5051         kill -USR1 $multipid
5052         wait $multipid || error "multiop close failed"
5053
5054         for (( i=0; i < 2; i++ )) ; do
5055                 local mtime2=`stat -c %Y $DIR1/$tfile`
5056
5057                 [ "$mtime2" = $TEST_39_MTIME ] || \
5058                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5059
5060                 cancel_lru_locks
5061                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5062         done
5063 }
5064 run_test 39k "write, utime, close, stat ========================"
5065
5066 # this should be set to future
5067 TEST_39_ATIME=`date -d "1 year" +%s`
5068
5069 test_39l() {
5070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5071         remote_mds_nodsh && skip "remote MDS with nodsh"
5072
5073         local atime_diff=$(do_facet $SINGLEMDS \
5074                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5075         rm -rf $DIR/$tdir
5076         mkdir_on_mdt0 $DIR/$tdir
5077
5078         # test setting directory atime to future
5079         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5080         local atime=$(stat -c %X $DIR/$tdir)
5081         [ "$atime" = $TEST_39_ATIME ] ||
5082                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5083
5084         # test setting directory atime from future to now
5085         local now=$(date +%s)
5086         touch -a -d @$now $DIR/$tdir
5087
5088         atime=$(stat -c %X $DIR/$tdir)
5089         [ "$atime" -eq "$now"  ] ||
5090                 error "atime is not updated from future: $atime, $now"
5091
5092         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5093         sleep 3
5094
5095         # test setting directory atime when now > dir atime + atime_diff
5096         local d1=$(date +%s)
5097         ls $DIR/$tdir
5098         local d2=$(date +%s)
5099         cancel_lru_locks mdc
5100         atime=$(stat -c %X $DIR/$tdir)
5101         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5102                 error "atime is not updated  : $atime, should be $d2"
5103
5104         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5105         sleep 3
5106
5107         # test not setting directory atime when now < dir atime + atime_diff
5108         ls $DIR/$tdir
5109         cancel_lru_locks mdc
5110         atime=$(stat -c %X $DIR/$tdir)
5111         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5112                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5113
5114         do_facet $SINGLEMDS \
5115                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5116 }
5117 run_test 39l "directory atime update ==========================="
5118
5119 test_39m() {
5120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5121
5122         touch $DIR1/$tfile
5123         sleep 2
5124         local far_past_mtime=$(date -d "May 29 1953" +%s)
5125         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5126
5127         touch -m -d @$far_past_mtime $DIR1/$tfile
5128         touch -a -d @$far_past_atime $DIR1/$tfile
5129
5130         for (( i=0; i < 2; i++ )) ; do
5131                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5132                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5133                         error "atime or mtime set incorrectly"
5134
5135                 cancel_lru_locks $OSC
5136                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5137         done
5138 }
5139 run_test 39m "test atime and mtime before 1970"
5140
5141 test_39n() { # LU-3832
5142         remote_mds_nodsh && skip "remote MDS with nodsh"
5143
5144         local atime_diff=$(do_facet $SINGLEMDS \
5145                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5146         local atime0
5147         local atime1
5148         local atime2
5149
5150         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5151
5152         rm -rf $DIR/$tfile
5153         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5154         atime0=$(stat -c %X $DIR/$tfile)
5155
5156         sleep 5
5157         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5158         atime1=$(stat -c %X $DIR/$tfile)
5159
5160         sleep 5
5161         cancel_lru_locks mdc
5162         cancel_lru_locks osc
5163         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5164         atime2=$(stat -c %X $DIR/$tfile)
5165
5166         do_facet $SINGLEMDS \
5167                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5168
5169         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5170         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5171 }
5172 run_test 39n "check that O_NOATIME is honored"
5173
5174 test_39o() {
5175         TESTDIR=$DIR/$tdir/$tfile
5176         [ -e $TESTDIR ] && rm -rf $TESTDIR
5177         mkdir -p $TESTDIR
5178         cd $TESTDIR
5179         links1=2
5180         ls
5181         mkdir a b
5182         ls
5183         links2=$(stat -c %h .)
5184         [ $(($links1 + 2)) != $links2 ] &&
5185                 error "wrong links count $(($links1 + 2)) != $links2"
5186         rmdir b
5187         links3=$(stat -c %h .)
5188         [ $(($links1 + 1)) != $links3 ] &&
5189                 error "wrong links count $links1 != $links3"
5190         return 0
5191 }
5192 run_test 39o "directory cached attributes updated after create"
5193
5194 test_39p() {
5195         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5196
5197         local MDTIDX=1
5198         TESTDIR=$DIR/$tdir/$tdir
5199         [ -e $TESTDIR ] && rm -rf $TESTDIR
5200         test_mkdir -p $TESTDIR
5201         cd $TESTDIR
5202         links1=2
5203         ls
5204         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5205         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5206         ls
5207         links2=$(stat -c %h .)
5208         [ $(($links1 + 2)) != $links2 ] &&
5209                 error "wrong links count $(($links1 + 2)) != $links2"
5210         rmdir remote_dir2
5211         links3=$(stat -c %h .)
5212         [ $(($links1 + 1)) != $links3 ] &&
5213                 error "wrong links count $links1 != $links3"
5214         return 0
5215 }
5216 run_test 39p "remote directory cached attributes updated after create ========"
5217
5218 test_39r() {
5219         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5220                 skip "no atime update on old OST"
5221         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5222                 skip_env "ldiskfs only test"
5223         fi
5224
5225         local saved_adiff
5226         saved_adiff=$(do_facet ost1 \
5227                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5228         stack_trap "do_facet ost1 \
5229                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5230
5231         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5232
5233         $LFS setstripe -i 0 $DIR/$tfile
5234         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5235                 error "can't write initial file"
5236         cancel_lru_locks osc
5237
5238         # exceed atime_diff and access file
5239         sleep 10
5240         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5241                 error "can't udpate atime"
5242
5243         local atime_cli=$(stat -c %X $DIR/$tfile)
5244         echo "client atime: $atime_cli"
5245         # allow atime update to be written to device
5246         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5247         sleep 5
5248
5249         local ostdev=$(ostdevname 1)
5250         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5251         local seq=${fid[3]#0x}
5252         local oid=${fid[1]}
5253         local oid_hex
5254
5255         if [ $seq == 0 ]; then
5256                 oid_hex=${fid[1]}
5257         else
5258                 oid_hex=${fid[2]#0x}
5259         fi
5260         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5261         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5262
5263         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5264         local atime_ost=$(do_facet ost1 "$cmd" |&
5265                           awk -F'[: ]' '/atime:/ { print $4 }')
5266         (( atime_cli == atime_ost )) ||
5267                 error "atime on client $atime_cli != ost $atime_ost"
5268 }
5269 run_test 39r "lazy atime update on OST"
5270
5271 test_39q() { # LU-8041
5272         local testdir=$DIR/$tdir
5273         mkdir -p $testdir
5274         multiop_bg_pause $testdir D_c || error "multiop failed"
5275         local multipid=$!
5276         cancel_lru_locks mdc
5277         kill -USR1 $multipid
5278         local atime=$(stat -c %X $testdir)
5279         [ "$atime" -ne 0 ] || error "atime is zero"
5280 }
5281 run_test 39q "close won't zero out atime"
5282
5283 test_39s() {
5284         local atime0
5285         local atime1
5286         local atime2
5287         local atime3
5288         local atime4
5289
5290         umount_client $MOUNT
5291         mount_client $MOUNT relatime
5292
5293         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5294         atime0=$(stat -c %X $DIR/$tfile)
5295
5296         # First read updates atime
5297         sleep 1
5298         cat $DIR/$tfile >/dev/null
5299         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5300
5301         # Next reads do not update atime
5302         sleep 1
5303         cat $DIR/$tfile >/dev/null
5304         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5305
5306         # If mtime is greater than atime, atime is updated
5307         sleep 1
5308         touch -m $DIR/$tfile # (mtime = now)
5309         sleep 1
5310         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5311         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5312
5313         # Next reads do not update atime
5314         sleep 1
5315         cat $DIR/$tfile >/dev/null
5316         atime4=$(stat -c %X $DIR/$tfile)
5317
5318         # Remount the client to clear 'relatime' option
5319         remount_client $MOUNT
5320
5321         (( atime0 < atime1 )) ||
5322                 error "atime $atime0 should be smaller than $atime1"
5323         (( atime1 == atime2 )) ||
5324                 error "atime $atime1 was updated to $atime2"
5325         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5326         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5327 }
5328 run_test 39s "relatime is supported"
5329
5330 test_40() {
5331         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5332         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5333                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5334         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5335                 error "$tfile is not 4096 bytes in size"
5336 }
5337 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5338
5339 test_41() {
5340         # bug 1553
5341         small_write $DIR/f41 18
5342 }
5343 run_test 41 "test small file write + fstat ====================="
5344
5345 count_ost_writes() {
5346         lctl get_param -n ${OSC}.*.stats |
5347                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5348                         END { printf("%0.0f", writes) }'
5349 }
5350
5351 # decent default
5352 WRITEBACK_SAVE=500
5353 DIRTY_RATIO_SAVE=40
5354 MAX_DIRTY_RATIO=50
5355 BG_DIRTY_RATIO_SAVE=10
5356 MAX_BG_DIRTY_RATIO=25
5357
5358 start_writeback() {
5359         trap 0
5360         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5361         # dirty_ratio, dirty_background_ratio
5362         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5363                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5364                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5365                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5366         else
5367                 # if file not here, we are a 2.4 kernel
5368                 kill -CONT `pidof kupdated`
5369         fi
5370 }
5371
5372 stop_writeback() {
5373         # setup the trap first, so someone cannot exit the test at the
5374         # exact wrong time and mess up a machine
5375         trap start_writeback EXIT
5376         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5377         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5378                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5379                 sysctl -w vm.dirty_writeback_centisecs=0
5380                 sysctl -w vm.dirty_writeback_centisecs=0
5381                 # save and increase /proc/sys/vm/dirty_ratio
5382                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5383                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5384                 # save and increase /proc/sys/vm/dirty_background_ratio
5385                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5386                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5387         else
5388                 # if file not here, we are a 2.4 kernel
5389                 kill -STOP `pidof kupdated`
5390         fi
5391 }
5392
5393 # ensure that all stripes have some grant before we test client-side cache
5394 setup_test42() {
5395         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5396                 dd if=/dev/zero of=$i bs=4k count=1
5397                 rm $i
5398         done
5399 }
5400
5401 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5402 # file truncation, and file removal.
5403 test_42a() {
5404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5405
5406         setup_test42
5407         cancel_lru_locks $OSC
5408         stop_writeback
5409         sync; sleep 1; sync # just to be safe
5410         BEFOREWRITES=`count_ost_writes`
5411         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5412         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5413         AFTERWRITES=`count_ost_writes`
5414         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5415                 error "$BEFOREWRITES < $AFTERWRITES"
5416         start_writeback
5417 }
5418 run_test 42a "ensure that we don't flush on close"
5419
5420 test_42b() {
5421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5422
5423         setup_test42
5424         cancel_lru_locks $OSC
5425         stop_writeback
5426         sync
5427         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5428         BEFOREWRITES=$(count_ost_writes)
5429         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5430         AFTERWRITES=$(count_ost_writes)
5431         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5432                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5433         fi
5434         BEFOREWRITES=$(count_ost_writes)
5435         sync || error "sync: $?"
5436         AFTERWRITES=$(count_ost_writes)
5437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5438                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5439         fi
5440         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5441         start_writeback
5442         return 0
5443 }
5444 run_test 42b "test destroy of file with cached dirty data ======"
5445
5446 # if these tests just want to test the effect of truncation,
5447 # they have to be very careful.  consider:
5448 # - the first open gets a {0,EOF}PR lock
5449 # - the first write conflicts and gets a {0, count-1}PW
5450 # - the rest of the writes are under {count,EOF}PW
5451 # - the open for truncate tries to match a {0,EOF}PR
5452 #   for the filesize and cancels the PWs.
5453 # any number of fixes (don't get {0,EOF} on open, match
5454 # composite locks, do smarter file size management) fix
5455 # this, but for now we want these tests to verify that
5456 # the cancellation with truncate intent works, so we
5457 # start the file with a full-file pw lock to match against
5458 # until the truncate.
5459 trunc_test() {
5460         test=$1
5461         file=$DIR/$test
5462         offset=$2
5463         cancel_lru_locks $OSC
5464         stop_writeback
5465         # prime the file with 0,EOF PW to match
5466         touch $file
5467         $TRUNCATE $file 0
5468         sync; sync
5469         # now the real test..
5470         dd if=/dev/zero of=$file bs=1024 count=100
5471         BEFOREWRITES=`count_ost_writes`
5472         $TRUNCATE $file $offset
5473         cancel_lru_locks $OSC
5474         AFTERWRITES=`count_ost_writes`
5475         start_writeback
5476 }
5477
5478 test_42c() {
5479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5480
5481         trunc_test 42c 1024
5482         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5483                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5484         rm $file
5485 }
5486 run_test 42c "test partial truncate of file with cached dirty data"
5487
5488 test_42d() {
5489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5490
5491         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5492         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5493         $LCTL set_param debug=+cache
5494
5495         trunc_test 42d 0
5496         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5497                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5498         rm $file
5499 }
5500 run_test 42d "test complete truncate of file with cached dirty data"
5501
5502 test_42e() { # bug22074
5503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5504
5505         local TDIR=$DIR/${tdir}e
5506         local pages=16 # hardcoded 16 pages, don't change it.
5507         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5508         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5509         local max_dirty_mb
5510         local warmup_files
5511
5512         test_mkdir $DIR/${tdir}e
5513         $LFS setstripe -c 1 $TDIR
5514         createmany -o $TDIR/f $files
5515
5516         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5517
5518         # we assume that with $OSTCOUNT files, at least one of them will
5519         # be allocated on OST0.
5520         warmup_files=$((OSTCOUNT * max_dirty_mb))
5521         createmany -o $TDIR/w $warmup_files
5522
5523         # write a large amount of data into one file and sync, to get good
5524         # avail_grant number from OST.
5525         for ((i=0; i<$warmup_files; i++)); do
5526                 idx=$($LFS getstripe -i $TDIR/w$i)
5527                 [ $idx -ne 0 ] && continue
5528                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5529                 break
5530         done
5531         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5532         sync
5533         $LCTL get_param $proc_osc0/cur_dirty_bytes
5534         $LCTL get_param $proc_osc0/cur_grant_bytes
5535
5536         # create as much dirty pages as we can while not to trigger the actual
5537         # RPCs directly. but depends on the env, VFS may trigger flush during this
5538         # period, hopefully we are good.
5539         for ((i=0; i<$warmup_files; i++)); do
5540                 idx=$($LFS getstripe -i $TDIR/w$i)
5541                 [ $idx -ne 0 ] && continue
5542                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5543         done
5544         $LCTL get_param $proc_osc0/cur_dirty_bytes
5545         $LCTL get_param $proc_osc0/cur_grant_bytes
5546
5547         # perform the real test
5548         $LCTL set_param $proc_osc0/rpc_stats 0
5549         for ((;i<$files; i++)); do
5550                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5551                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5552         done
5553         sync
5554         $LCTL get_param $proc_osc0/rpc_stats
5555
5556         local percent=0
5557         local have_ppr=false
5558         $LCTL get_param $proc_osc0/rpc_stats |
5559                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5560                         # skip lines until we are at the RPC histogram data
5561                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5562                         $have_ppr || continue
5563
5564                         # we only want the percent stat for < 16 pages
5565                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5566
5567                         percent=$((percent + WPCT))
5568                         if [[ $percent -gt 15 ]]; then
5569                                 error "less than 16-pages write RPCs" \
5570                                       "$percent% > 15%"
5571                                 break
5572                         fi
5573                 done
5574         rm -rf $TDIR
5575 }
5576 run_test 42e "verify sub-RPC writes are not done synchronously"
5577
5578 test_43A() { # was test_43
5579         test_mkdir $DIR/$tdir
5580         cp -p /bin/ls $DIR/$tdir/$tfile
5581         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5582         pid=$!
5583         # give multiop a chance to open
5584         sleep 1
5585
5586         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5587         kill -USR1 $pid
5588         # Wait for multiop to exit
5589         wait $pid
5590 }
5591 run_test 43A "execution of file opened for write should return -ETXTBSY"
5592
5593 test_43a() {
5594         test_mkdir $DIR/$tdir
5595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5596         $DIR/$tdir/sleep 60 &
5597         SLEEP_PID=$!
5598         # Make sure exec of $tdir/sleep wins race with truncate
5599         sleep 1
5600         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5601         kill $SLEEP_PID
5602 }
5603 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5604
5605 test_43b() {
5606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5607
5608         test_mkdir $DIR/$tdir
5609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5610         $DIR/$tdir/sleep 60 &
5611         SLEEP_PID=$!
5612         # Make sure exec of $tdir/sleep wins race with truncate
5613         sleep 1
5614         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5615         kill $SLEEP_PID
5616 }
5617 run_test 43b "truncate of file being executed should return -ETXTBSY"
5618
5619 test_43c() {
5620         local testdir="$DIR/$tdir"
5621         test_mkdir $testdir
5622         cp $SHELL $testdir/
5623         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5624                 ( cd $testdir && md5sum -c )
5625 }
5626 run_test 43c "md5sum of copy into lustre"
5627
5628 test_44A() { # was test_44
5629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5630
5631         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5632         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5633 }
5634 run_test 44A "zero length read from a sparse stripe"
5635
5636 test_44a() {
5637         local nstripe=$($LFS getstripe -c -d $DIR)
5638         [ -z "$nstripe" ] && skip "can't get stripe info"
5639         [[ $nstripe -gt $OSTCOUNT ]] &&
5640                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5641
5642         local stride=$($LFS getstripe -S -d $DIR)
5643         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5644                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5645         fi
5646
5647         OFFSETS="0 $((stride/2)) $((stride-1))"
5648         for offset in $OFFSETS; do
5649                 for i in $(seq 0 $((nstripe-1))); do
5650                         local GLOBALOFFSETS=""
5651                         # size in Bytes
5652                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5653                         local myfn=$DIR/d44a-$size
5654                         echo "--------writing $myfn at $size"
5655                         ll_sparseness_write $myfn $size ||
5656                                 error "ll_sparseness_write"
5657                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5658                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5659                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5660
5661                         for j in $(seq 0 $((nstripe-1))); do
5662                                 # size in Bytes
5663                                 size=$((((j + $nstripe )*$stride + $offset)))
5664                                 ll_sparseness_write $myfn $size ||
5665                                         error "ll_sparseness_write"
5666                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5667                         done
5668                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5669                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5670                         rm -f $myfn
5671                 done
5672         done
5673 }
5674 run_test 44a "test sparse pwrite ==============================="
5675
5676 dirty_osc_total() {
5677         tot=0
5678         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5679                 tot=$(($tot + $d))
5680         done
5681         echo $tot
5682 }
5683 do_dirty_record() {
5684         before=`dirty_osc_total`
5685         echo executing "\"$*\""
5686         eval $*
5687         after=`dirty_osc_total`
5688         echo before $before, after $after
5689 }
5690 test_45() {
5691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5692
5693         f="$DIR/f45"
5694         # Obtain grants from OST if it supports it
5695         echo blah > ${f}_grant
5696         stop_writeback
5697         sync
5698         do_dirty_record "echo blah > $f"
5699         [[ $before -eq $after ]] && error "write wasn't cached"
5700         do_dirty_record "> $f"
5701         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5702         do_dirty_record "echo blah > $f"
5703         [[ $before -eq $after ]] && error "write wasn't cached"
5704         do_dirty_record "sync"
5705         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5706         do_dirty_record "echo blah > $f"
5707         [[ $before -eq $after ]] && error "write wasn't cached"
5708         do_dirty_record "cancel_lru_locks osc"
5709         [[ $before -gt $after ]] ||
5710                 error "lock cancellation didn't lower dirty count"
5711         start_writeback
5712 }
5713 run_test 45 "osc io page accounting ============================"
5714
5715 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5716 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5717 # objects offset and an assert hit when an rpc was built with 1023's mapped
5718 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5719 test_46() {
5720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5721
5722         f="$DIR/f46"
5723         stop_writeback
5724         sync
5725         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5726         sync
5727         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5728         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5729         sync
5730         start_writeback
5731 }
5732 run_test 46 "dirtying a previously written page ================"
5733
5734 # test_47 is removed "Device nodes check" is moved to test_28
5735
5736 test_48a() { # bug 2399
5737         [ "$mds1_FSTYPE" = "zfs" ] &&
5738         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5739                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5740
5741         test_mkdir $DIR/$tdir
5742         cd $DIR/$tdir
5743         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5744         test_mkdir $DIR/$tdir
5745         touch foo || error "'touch foo' failed after recreating cwd"
5746         test_mkdir bar
5747         touch .foo || error "'touch .foo' failed after recreating cwd"
5748         test_mkdir .bar
5749         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5750         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5751         cd . || error "'cd .' failed after recreating cwd"
5752         mkdir . && error "'mkdir .' worked after recreating cwd"
5753         rmdir . && error "'rmdir .' worked after recreating cwd"
5754         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5755         cd .. || error "'cd ..' failed after recreating cwd"
5756 }
5757 run_test 48a "Access renamed working dir (should return errors)="
5758
5759 test_48b() { # bug 2399
5760         rm -rf $DIR/$tdir
5761         test_mkdir $DIR/$tdir
5762         cd $DIR/$tdir
5763         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5764         touch foo && error "'touch foo' worked after removing cwd"
5765         mkdir foo && error "'mkdir foo' worked after removing cwd"
5766         touch .foo && error "'touch .foo' worked after removing cwd"
5767         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5768         ls . > /dev/null && error "'ls .' worked after removing cwd"
5769         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5770         mkdir . && error "'mkdir .' worked after removing cwd"
5771         rmdir . && error "'rmdir .' worked after removing cwd"
5772         ln -s . foo && error "'ln -s .' worked after removing cwd"
5773         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5774 }
5775 run_test 48b "Access removed working dir (should return errors)="
5776
5777 test_48c() { # bug 2350
5778         #lctl set_param debug=-1
5779         #set -vx
5780         rm -rf $DIR/$tdir
5781         test_mkdir -p $DIR/$tdir/dir
5782         cd $DIR/$tdir/dir
5783         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5784         $TRACE touch foo && error "touch foo worked after removing cwd"
5785         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5786         touch .foo && error "touch .foo worked after removing cwd"
5787         mkdir .foo && error "mkdir .foo worked after removing cwd"
5788         $TRACE ls . && error "'ls .' worked after removing cwd"
5789         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5790         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5791         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5792         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5793         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5794 }
5795 run_test 48c "Access removed working subdir (should return errors)"
5796
5797 test_48d() { # bug 2350
5798         #lctl set_param debug=-1
5799         #set -vx
5800         rm -rf $DIR/$tdir
5801         test_mkdir -p $DIR/$tdir/dir
5802         cd $DIR/$tdir/dir
5803         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5804         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5805         $TRACE touch foo && error "'touch foo' worked after removing parent"
5806         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5807         touch .foo && error "'touch .foo' worked after removing parent"
5808         mkdir .foo && error "mkdir .foo worked after removing parent"
5809         $TRACE ls . && error "'ls .' worked after removing parent"
5810         $TRACE ls .. && error "'ls ..' worked after removing parent"
5811         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5812         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5813         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5814         true
5815 }
5816 run_test 48d "Access removed parent subdir (should return errors)"
5817
5818 test_48e() { # bug 4134
5819         #lctl set_param debug=-1
5820         #set -vx
5821         rm -rf $DIR/$tdir
5822         test_mkdir -p $DIR/$tdir/dir
5823         cd $DIR/$tdir/dir
5824         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5825         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5826         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5827         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5828         # On a buggy kernel addition of "touch foo" after cd .. will
5829         # produce kernel oops in lookup_hash_it
5830         touch ../foo && error "'cd ..' worked after recreate parent"
5831         cd $DIR
5832         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5833 }
5834 run_test 48e "Access to recreated parent subdir (should return errors)"
5835
5836 test_48f() {
5837         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5838                 skip "need MDS >= 2.13.55"
5839         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5840         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5841                 skip "needs different host for mdt1 mdt2"
5842         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5843
5844         $LFS mkdir -i0 $DIR/$tdir
5845         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5846
5847         for d in sub1 sub2 sub3; do
5848                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5849                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5850                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5851         done
5852
5853         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5854 }
5855 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5856
5857 test_49() { # LU-1030
5858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5859         remote_ost_nodsh && skip "remote OST with nodsh"
5860
5861         # get ost1 size - $FSNAME-OST0000
5862         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5863                 awk '{ print $4 }')
5864         # write 800M at maximum
5865         [[ $ost1_size -lt 2 ]] && ost1_size=2
5866         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5867
5868         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5869         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5870         local dd_pid=$!
5871
5872         # change max_pages_per_rpc while writing the file
5873         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5874         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5875         # loop until dd process exits
5876         while ps ax -opid | grep -wq $dd_pid; do
5877                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5878                 sleep $((RANDOM % 5 + 1))
5879         done
5880         # restore original max_pages_per_rpc
5881         $LCTL set_param $osc1_mppc=$orig_mppc
5882         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5883 }
5884 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5885
5886 test_50() {
5887         # bug 1485
5888         test_mkdir $DIR/$tdir
5889         cd $DIR/$tdir
5890         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5891 }
5892 run_test 50 "special situations: /proc symlinks  ==============="
5893
5894 test_51a() {    # was test_51
5895         # bug 1516 - create an empty entry right after ".." then split dir
5896         test_mkdir -c1 $DIR/$tdir
5897         touch $DIR/$tdir/foo
5898         $MCREATE $DIR/$tdir/bar
5899         rm $DIR/$tdir/foo
5900         createmany -m $DIR/$tdir/longfile 201
5901         FNUM=202
5902         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5903                 $MCREATE $DIR/$tdir/longfile$FNUM
5904                 FNUM=$(($FNUM + 1))
5905                 echo -n "+"
5906         done
5907         echo
5908         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5909 }
5910 run_test 51a "special situations: split htree with empty entry =="
5911
5912 cleanup_print_lfs_df () {
5913         trap 0
5914         $LFS df
5915         $LFS df -i
5916 }
5917
5918 test_51b() {
5919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5920
5921         local dir=$DIR/$tdir
5922         local nrdirs=$((65536 + 100))
5923
5924         # cleanup the directory
5925         rm -fr $dir
5926
5927         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5928
5929         $LFS df
5930         $LFS df -i
5931         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5932         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5933         [[ $numfree -lt $nrdirs ]] &&
5934                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5935
5936         # need to check free space for the directories as well
5937         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5938         numfree=$(( blkfree / $(fs_inode_ksize) ))
5939         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5940
5941         trap cleanup_print_lfs_df EXIT
5942
5943         # create files
5944         createmany -d $dir/d $nrdirs || {
5945                 unlinkmany $dir/d $nrdirs
5946                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5947         }
5948
5949         # really created :
5950         nrdirs=$(ls -U $dir | wc -l)
5951
5952         # unlink all but 100 subdirectories, then check it still works
5953         local left=100
5954         local delete=$((nrdirs - left))
5955
5956         $LFS df
5957         $LFS df -i
5958
5959         # for ldiskfs the nlink count should be 1, but this is OSD specific
5960         # and so this is listed for informational purposes only
5961         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5962         unlinkmany -d $dir/d $delete ||
5963                 error "unlink of first $delete subdirs failed"
5964
5965         echo "nlink between: $(stat -c %h $dir)"
5966         local found=$(ls -U $dir | wc -l)
5967         [ $found -ne $left ] &&
5968                 error "can't find subdirs: found only $found, expected $left"
5969
5970         unlinkmany -d $dir/d $delete $left ||
5971                 error "unlink of second $left subdirs failed"
5972         # regardless of whether the backing filesystem tracks nlink accurately
5973         # or not, the nlink count shouldn't be more than "." and ".." here
5974         local after=$(stat -c %h $dir)
5975         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5976                 echo "nlink after: $after"
5977
5978         cleanup_print_lfs_df
5979 }
5980 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5981
5982 test_51d_sub() {
5983         local stripecount=$1
5984         local nfiles=$2
5985
5986         log "create files with stripecount=$stripecount"
5987         $LFS setstripe -C $stripecount $DIR/$tdir
5988         createmany -o $DIR/$tdir/t- $nfiles
5989         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5990         for ((n = 0; n < $OSTCOUNT; n++)); do
5991                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5992                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5993                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5994                             '($1 == '$n') { objs += 1 } \
5995                             END { printf("%0.0f", objs) }')
5996                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5997         done
5998         unlinkmany $DIR/$tdir/t- $nfiles
5999         rm  -f $TMP/$tfile
6000
6001         local nlast
6002         local min=4
6003         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6004
6005         # For some combinations of stripecount and OSTCOUNT current code
6006         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6007         # than others. Rather than skipping this test entirely, check that
6008         # and keep testing to ensure imbalance does not get worse. LU-15282
6009         (( (OSTCOUNT == 6 && stripecount == 4) ||
6010            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6011            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6012         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6013                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6014                         { $LFS df && $LFS df -i &&
6015                         error "stripecount=$stripecount: " \
6016                               "OST $n has fewer objects vs. OST $nlast " \
6017                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6018                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6019                         { $LFS df && $LFS df -i &&
6020                         error "stripecount=$stripecount: " \
6021                               "OST $n has more objects vs. OST $nlast " \
6022                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6023
6024                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6025                         { $LFS df && $LFS df -i &&
6026                         error "stripecount=$stripecount: " \
6027                               "OST $n has fewer #0 objects vs. OST $nlast " \
6028                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6029                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6030                         { $LFS df && $LFS df -i &&
6031                         error "stripecount=$stripecount: " \
6032                               "OST $n has more #0 objects vs. OST $nlast " \
6033                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6034         done
6035 }
6036
6037 test_51d() {
6038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6039         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6040
6041         local stripecount
6042         local per_ost=100
6043         local nfiles=$((per_ost * OSTCOUNT))
6044         local mdts=$(comma_list $(mdts_nodes))
6045         local param="osp.*.create_count"
6046         local qos_old=$(do_facet mds1 \
6047                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6048
6049         do_nodes $mdts \
6050                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6051         stack_trap "do_nodes $mdts \
6052                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6053
6054         test_mkdir $DIR/$tdir
6055         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6056         (( dirstripes > 0 )) || dirstripes=1
6057
6058         # Ensure enough OST objects precreated for tests to pass without
6059         # running out of objects.  This is an LOV r-r OST algorithm test,
6060         # not an OST object precreation test.
6061         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6062         (( old >= nfiles )) ||
6063         {
6064                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6065
6066                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6067                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6068
6069                 # trigger precreation from all MDTs for all OSTs
6070                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6071                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6072                 done
6073         }
6074
6075         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6076                 sleep 8  # allow object precreation to catch up
6077                 test_51d_sub $stripecount $nfiles
6078         done
6079 }
6080 run_test 51d "check LOV round-robin OST object distribution"
6081
6082 test_51e() {
6083         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6084                 skip_env "ldiskfs only test"
6085         fi
6086
6087         test_mkdir -c1 $DIR/$tdir
6088         test_mkdir -c1 $DIR/$tdir/d0
6089
6090         touch $DIR/$tdir/d0/foo
6091         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6092                 error "file exceed 65000 nlink limit!"
6093         unlinkmany $DIR/$tdir/d0/f- 65001
6094         return 0
6095 }
6096 run_test 51e "check file nlink limit"
6097
6098 test_51f() {
6099         test_mkdir $DIR/$tdir
6100
6101         local max=100000
6102         local ulimit_old=$(ulimit -n)
6103         local spare=20 # number of spare fd's for scripts/libraries, etc.
6104         local mdt=$($LFS getstripe -m $DIR/$tdir)
6105         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6106
6107         echo "MDT$mdt numfree=$numfree, max=$max"
6108         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6109         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6110                 while ! ulimit -n $((numfree + spare)); do
6111                         numfree=$((numfree * 3 / 4))
6112                 done
6113                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6114         else
6115                 echo "left ulimit at $ulimit_old"
6116         fi
6117
6118         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6119                 unlinkmany $DIR/$tdir/f $numfree
6120                 error "create+open $numfree files in $DIR/$tdir failed"
6121         }
6122         ulimit -n $ulimit_old
6123
6124         # if createmany exits at 120s there will be fewer than $numfree files
6125         unlinkmany $DIR/$tdir/f $numfree || true
6126 }
6127 run_test 51f "check many open files limit"
6128
6129 test_52a() {
6130         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6131         test_mkdir $DIR/$tdir
6132         touch $DIR/$tdir/foo
6133         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6134         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6135         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6136         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6137         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6138                                         error "link worked"
6139         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6140         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6141         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6142                                                      error "lsattr"
6143         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6144         cp -r $DIR/$tdir $TMP/
6145         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6146 }
6147 run_test 52a "append-only flag test (should return errors)"
6148
6149 test_52b() {
6150         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6151         test_mkdir $DIR/$tdir
6152         touch $DIR/$tdir/foo
6153         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6154         cat test > $DIR/$tdir/foo && error "cat test worked"
6155         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6156         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6157         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6158                                         error "link worked"
6159         echo foo >> $DIR/$tdir/foo && error "echo worked"
6160         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6161         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6162         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6163         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6164                                                         error "lsattr"
6165         chattr -i $DIR/$tdir/foo || error "chattr failed"
6166
6167         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6168 }
6169 run_test 52b "immutable flag test (should return errors) ======="
6170
6171 test_53() {
6172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6173         remote_mds_nodsh && skip "remote MDS with nodsh"
6174         remote_ost_nodsh && skip "remote OST with nodsh"
6175
6176         local param
6177         local param_seq
6178         local ostname
6179         local mds_last
6180         local mds_last_seq
6181         local ost_last
6182         local ost_last_seq
6183         local ost_last_id
6184         local ostnum
6185         local node
6186         local found=false
6187         local support_last_seq=true
6188
6189         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6190                 support_last_seq=false
6191
6192         # only test MDT0000
6193         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6194         local value
6195         for value in $(do_facet $SINGLEMDS \
6196                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6197                 param=$(echo ${value[0]} | cut -d "=" -f1)
6198                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6199
6200                 if $support_last_seq; then
6201                         param_seq=$(echo $param |
6202                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6203                         mds_last_seq=$(do_facet $SINGLEMDS \
6204                                        $LCTL get_param -n $param_seq)
6205                 fi
6206                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6207
6208                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6209                 node=$(facet_active_host ost$((ostnum+1)))
6210                 param="obdfilter.$ostname.last_id"
6211                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6212                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6213                         ost_last_id=$ost_last
6214
6215                         if $support_last_seq; then
6216                                 ost_last_id=$(echo $ost_last |
6217                                               awk -F':' '{print $2}' |
6218                                               sed -e "s/^0x//g")
6219                                 ost_last_seq=$(echo $ost_last |
6220                                                awk -F':' '{print $1}')
6221                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6222                         fi
6223
6224                         if [[ $ost_last_id != $mds_last ]]; then
6225                                 error "$ost_last_id != $mds_last"
6226                         else
6227                                 found=true
6228                                 break
6229                         fi
6230                 done
6231         done
6232         $found || error "can not match last_seq/last_id for $mdtosc"
6233         return 0
6234 }
6235 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6236
6237 test_54a() {
6238         perl -MSocket -e ';' || skip "no Socket perl module installed"
6239
6240         $SOCKETSERVER $DIR/socket ||
6241                 error "$SOCKETSERVER $DIR/socket failed: $?"
6242         $SOCKETCLIENT $DIR/socket ||
6243                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6244         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6245 }
6246 run_test 54a "unix domain socket test =========================="
6247
6248 test_54b() {
6249         f="$DIR/f54b"
6250         mknod $f c 1 3
6251         chmod 0666 $f
6252         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6253 }
6254 run_test 54b "char device works in lustre ======================"
6255
6256 find_loop_dev() {
6257         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6258         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6259         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6260
6261         for i in $(seq 3 7); do
6262                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6263                 LOOPDEV=$LOOPBASE$i
6264                 LOOPNUM=$i
6265                 break
6266         done
6267 }
6268
6269 cleanup_54c() {
6270         local rc=0
6271         loopdev="$DIR/loop54c"
6272
6273         trap 0
6274         $UMOUNT $DIR/$tdir || rc=$?
6275         losetup -d $loopdev || true
6276         losetup -d $LOOPDEV || true
6277         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6278         return $rc
6279 }
6280
6281 test_54c() {
6282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6283
6284         loopdev="$DIR/loop54c"
6285
6286         find_loop_dev
6287         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6288         trap cleanup_54c EXIT
6289         mknod $loopdev b 7 $LOOPNUM
6290         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6291         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6292         losetup $loopdev $DIR/$tfile ||
6293                 error "can't set up $loopdev for $DIR/$tfile"
6294         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6295         test_mkdir $DIR/$tdir
6296         mount -t ext2 $loopdev $DIR/$tdir ||
6297                 error "error mounting $loopdev on $DIR/$tdir"
6298         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6299                 error "dd write"
6300         df $DIR/$tdir
6301         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6302                 error "dd read"
6303         cleanup_54c
6304 }
6305 run_test 54c "block device works in lustre ====================="
6306
6307 test_54d() {
6308         local pipe="$DIR/$tfile.pipe"
6309         local string="aaaaaa"
6310
6311         mknod $pipe p
6312         echo -n "$string" > $pipe &
6313         local result=$(cat $pipe)
6314         [[ "$result" == "$string" ]] || error "$result != $string"
6315 }
6316 run_test 54d "fifo device works in lustre ======================"
6317
6318 test_54e() {
6319         f="$DIR/f54e"
6320         string="aaaaaa"
6321         cp -aL /dev/console $f
6322         echo $string > $f || error "echo $string to $f failed"
6323 }
6324 run_test 54e "console/tty device works in lustre ======================"
6325
6326 test_56a() {
6327         local numfiles=3
6328         local numdirs=2
6329         local dir=$DIR/$tdir
6330
6331         rm -rf $dir
6332         test_mkdir -p $dir/dir
6333         for i in $(seq $numfiles); do
6334                 touch $dir/file$i
6335                 touch $dir/dir/file$i
6336         done
6337
6338         local numcomp=$($LFS getstripe --component-count $dir)
6339
6340         [[ $numcomp == 0 ]] && numcomp=1
6341
6342         # test lfs getstripe with --recursive
6343         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6344
6345         [[ $filenum -eq $((numfiles * 2)) ]] ||
6346                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6347         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6348         [[ $filenum -eq $numfiles ]] ||
6349                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6350         echo "$LFS getstripe showed obdidx or l_ost_idx"
6351
6352         # test lfs getstripe with file instead of dir
6353         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6354         [[ $filenum -eq 1 ]] ||
6355                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6356         echo "$LFS getstripe file1 passed"
6357
6358         #test lfs getstripe with --verbose
6359         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6360         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6361                 error "$LFS getstripe --verbose $dir: "\
6362                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6363         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6364                 error "$LFS getstripe $dir: showed lmm_magic"
6365
6366         #test lfs getstripe with -v prints lmm_fid
6367         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6368         local countfids=$((numdirs + numfiles * numcomp))
6369         [[ $filenum -eq $countfids ]] ||
6370                 error "$LFS getstripe -v $dir: "\
6371                       "got $filenum want $countfids lmm_fid"
6372         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6373                 error "$LFS getstripe $dir: showed lmm_fid by default"
6374         echo "$LFS getstripe --verbose passed"
6375
6376         #check for FID information
6377         local fid1=$($LFS getstripe --fid $dir/file1)
6378         local fid2=$($LFS getstripe --verbose $dir/file1 |
6379                      awk '/lmm_fid: / { print $2; exit; }')
6380         local fid3=$($LFS path2fid $dir/file1)
6381
6382         [ "$fid1" != "$fid2" ] &&
6383                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6384         [ "$fid1" != "$fid3" ] &&
6385                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6386         echo "$LFS getstripe --fid passed"
6387
6388         #test lfs getstripe with --obd
6389         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6390                 error "$LFS getstripe --obd wrong_uuid: should return error"
6391
6392         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6393
6394         local ostidx=1
6395         local obduuid=$(ostuuid_from_index $ostidx)
6396         local found=$($LFS getstripe -r --obd $obduuid $dir |
6397                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6398
6399         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6400         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6401                 ((filenum--))
6402         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6403                 ((filenum--))
6404
6405         [[ $found -eq $filenum ]] ||
6406                 error "$LFS getstripe --obd: found $found expect $filenum"
6407         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6408                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6409                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6410                 error "$LFS getstripe --obd: should not show file on other obd"
6411         echo "$LFS getstripe --obd passed"
6412 }
6413 run_test 56a "check $LFS getstripe"
6414
6415 test_56b() {
6416         local dir=$DIR/$tdir
6417         local numdirs=3
6418
6419         test_mkdir $dir
6420         for i in $(seq $numdirs); do
6421                 test_mkdir $dir/dir$i
6422         done
6423
6424         # test lfs getdirstripe default mode is non-recursion, which is
6425         # different from lfs getstripe
6426         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6427
6428         [[ $dircnt -eq 1 ]] ||
6429                 error "$LFS getdirstripe: found $dircnt, not 1"
6430         dircnt=$($LFS getdirstripe --recursive $dir |
6431                 grep -c lmv_stripe_count)
6432         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6433                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6434 }
6435 run_test 56b "check $LFS getdirstripe"
6436
6437 test_56bb() {
6438         verify_yaml_available || skip_env "YAML verification not installed"
6439         local output_file=$DIR/$tfile.out
6440
6441         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6442
6443         cat $output_file
6444         cat $output_file | verify_yaml || error "layout is not valid YAML"
6445 }
6446 run_test 56bb "check $LFS getdirstripe layout is YAML"
6447
6448 test_56c() {
6449         remote_ost_nodsh && skip "remote OST with nodsh"
6450
6451         local ost_idx=0
6452         local ost_name=$(ostname_from_index $ost_idx)
6453         local old_status=$(ost_dev_status $ost_idx)
6454         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6455
6456         [[ -z "$old_status" ]] ||
6457                 skip_env "OST $ost_name is in $old_status status"
6458
6459         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6460         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6461                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6462         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6463                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6464                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6465         fi
6466
6467         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6468                 error "$LFS df -v showing inactive devices"
6469         sleep_maxage
6470
6471         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6472
6473         [[ "$new_status" =~ "D" ]] ||
6474                 error "$ost_name status is '$new_status', missing 'D'"
6475         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6476                 [[ "$new_status" =~ "N" ]] ||
6477                         error "$ost_name status is '$new_status', missing 'N'"
6478         fi
6479         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6480                 [[ "$new_status" =~ "f" ]] ||
6481                         error "$ost_name status is '$new_status', missing 'f'"
6482         fi
6483
6484         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6485         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6486                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6487         [[ -z "$p" ]] && restore_lustre_params < $p || true
6488         sleep_maxage
6489
6490         new_status=$(ost_dev_status $ost_idx)
6491         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6492                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6493         # can't check 'f' as devices may actually be on flash
6494 }
6495 run_test 56c "check 'lfs df' showing device status"
6496
6497 test_56d() {
6498         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6499         local osts=$($LFS df -v $MOUNT | grep -c OST)
6500
6501         $LFS df $MOUNT
6502
6503         (( mdts == MDSCOUNT )) ||
6504                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6505         (( osts == OSTCOUNT )) ||
6506                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6507 }
6508 run_test 56d "'lfs df -v' prints only configured devices"
6509
6510 test_56e() {
6511         err_enoent=2 # No such file or directory
6512         err_eopnotsupp=95 # Operation not supported
6513
6514         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6515         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6516
6517         # Check for handling of path not exists
6518         output=$($LFS df $enoent_mnt 2>&1)
6519         ret=$?
6520
6521         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6522         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6523                 error "expect failure $err_enoent, not $ret"
6524
6525         # Check for handling of non-Lustre FS
6526         output=$($LFS df $notsup_mnt)
6527         ret=$?
6528
6529         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6530         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6531                 error "expect success $err_eopnotsupp, not $ret"
6532
6533         # Check for multiple LustreFS argument
6534         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6535         ret=$?
6536
6537         [[ $output -eq 3 && $ret -eq 0 ]] ||
6538                 error "expect success 3, not $output, rc = $ret"
6539
6540         # Check for correct non-Lustre FS handling among multiple
6541         # LustreFS argument
6542         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6543                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6544         ret=$?
6545
6546         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6547                 error "expect success 2, not $output, rc = $ret"
6548 }
6549 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6550
6551 NUMFILES=3
6552 NUMDIRS=3
6553 setup_56() {
6554         local local_tdir="$1"
6555         local local_numfiles="$2"
6556         local local_numdirs="$3"
6557         local dir_params="$4"
6558         local dir_stripe_params="$5"
6559
6560         if [ ! -d "$local_tdir" ] ; then
6561                 test_mkdir -p $dir_stripe_params $local_tdir
6562                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6563                 for i in $(seq $local_numfiles) ; do
6564                         touch $local_tdir/file$i
6565                 done
6566                 for i in $(seq $local_numdirs) ; do
6567                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6568                         for j in $(seq $local_numfiles) ; do
6569                                 touch $local_tdir/dir$i/file$j
6570                         done
6571                 done
6572         fi
6573 }
6574
6575 setup_56_special() {
6576         local local_tdir=$1
6577         local local_numfiles=$2
6578         local local_numdirs=$3
6579
6580         setup_56 $local_tdir $local_numfiles $local_numdirs
6581
6582         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6583                 for i in $(seq $local_numfiles) ; do
6584                         mknod $local_tdir/loop${i}b b 7 $i
6585                         mknod $local_tdir/null${i}c c 1 3
6586                         ln -s $local_tdir/file1 $local_tdir/link${i}
6587                 done
6588                 for i in $(seq $local_numdirs) ; do
6589                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6590                         mknod $local_tdir/dir$i/null${i}c c 1 3
6591                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6592                 done
6593         fi
6594 }
6595
6596 test_56g() {
6597         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6598         local expected=$(($NUMDIRS + 2))
6599
6600         setup_56 $dir $NUMFILES $NUMDIRS
6601
6602         # test lfs find with -name
6603         for i in $(seq $NUMFILES) ; do
6604                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6605
6606                 [ $nums -eq $expected ] ||
6607                         error "lfs find -name '*$i' $dir wrong: "\
6608                               "found $nums, expected $expected"
6609         done
6610 }
6611 run_test 56g "check lfs find -name"
6612
6613 test_56h() {
6614         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6615         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6616
6617         setup_56 $dir $NUMFILES $NUMDIRS
6618
6619         # test lfs find with ! -name
6620         for i in $(seq $NUMFILES) ; do
6621                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6622
6623                 [ $nums -eq $expected ] ||
6624                         error "lfs find ! -name '*$i' $dir wrong: "\
6625                               "found $nums, expected $expected"
6626         done
6627 }
6628 run_test 56h "check lfs find ! -name"
6629
6630 test_56i() {
6631         local dir=$DIR/$tdir
6632
6633         test_mkdir $dir
6634
6635         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6636         local out=$($cmd)
6637
6638         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6639 }
6640 run_test 56i "check 'lfs find -ost UUID' skips directories"
6641
6642 test_56j() {
6643         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6644
6645         setup_56_special $dir $NUMFILES $NUMDIRS
6646
6647         local expected=$((NUMDIRS + 1))
6648         local cmd="$LFS find -type d $dir"
6649         local nums=$($cmd | wc -l)
6650
6651         [ $nums -eq $expected ] ||
6652                 error "'$cmd' wrong: found $nums, expected $expected"
6653 }
6654 run_test 56j "check lfs find -type d"
6655
6656 test_56k() {
6657         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6658
6659         setup_56_special $dir $NUMFILES $NUMDIRS
6660
6661         local expected=$(((NUMDIRS + 1) * NUMFILES))
6662         local cmd="$LFS find -type f $dir"
6663         local nums=$($cmd | wc -l)
6664
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56k "check lfs find -type f"
6669
6670 test_56l() {
6671         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6672
6673         setup_56_special $dir $NUMFILES $NUMDIRS
6674
6675         local expected=$((NUMDIRS + NUMFILES))
6676         local cmd="$LFS find -type b $dir"
6677         local nums=$($cmd | wc -l)
6678
6679         [ $nums -eq $expected ] ||
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681 }
6682 run_test 56l "check lfs find -type b"
6683
6684 test_56m() {
6685         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6686
6687         setup_56_special $dir $NUMFILES $NUMDIRS
6688
6689         local expected=$((NUMDIRS + NUMFILES))
6690         local cmd="$LFS find -type c $dir"
6691         local nums=$($cmd | wc -l)
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694 }
6695 run_test 56m "check lfs find -type c"
6696
6697 test_56n() {
6698         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6699         setup_56_special $dir $NUMFILES $NUMDIRS
6700
6701         local expected=$((NUMDIRS + NUMFILES))
6702         local cmd="$LFS find -type l $dir"
6703         local nums=$($cmd | wc -l)
6704
6705         [ $nums -eq $expected ] ||
6706                 error "'$cmd' wrong: found $nums, expected $expected"
6707 }
6708 run_test 56n "check lfs find -type l"
6709
6710 test_56o() {
6711         local dir=$DIR/$tdir
6712
6713         setup_56 $dir $NUMFILES $NUMDIRS
6714         utime $dir/file1 > /dev/null || error "utime (1)"
6715         utime $dir/file2 > /dev/null || error "utime (2)"
6716         utime $dir/dir1 > /dev/null || error "utime (3)"
6717         utime $dir/dir2 > /dev/null || error "utime (4)"
6718         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6719         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6720
6721         local expected=4
6722         local nums=$($LFS find -mtime +0 $dir | wc -l)
6723
6724         [ $nums -eq $expected ] ||
6725                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6726
6727         expected=12
6728         cmd="$LFS find -mtime 0 $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] ||
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732 }
6733 run_test 56o "check lfs find -mtime for old files"
6734
6735 test_56ob() {
6736         local dir=$DIR/$tdir
6737         local expected=1
6738         local count=0
6739
6740         # just to make sure there is something that won't be found
6741         test_mkdir $dir
6742         touch $dir/$tfile.now
6743
6744         for age in year week day hour min; do
6745                 count=$((count + 1))
6746
6747                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6748                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6749                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6750
6751                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6752                 local nums=$($cmd | wc -l)
6753                 [ $nums -eq $expected ] ||
6754                         error "'$cmd' wrong: found $nums, expected $expected"
6755
6756                 cmd="$LFS find $dir -atime $count${age:0:1}"
6757                 nums=$($cmd | wc -l)
6758                 [ $nums -eq $expected ] ||
6759                         error "'$cmd' wrong: found $nums, expected $expected"
6760         done
6761
6762         sleep 2
6763         cmd="$LFS find $dir -ctime +1s -type f"
6764         nums=$($cmd | wc -l)
6765         (( $nums == $count * 2 + 1)) ||
6766                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6767 }
6768 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6769
6770 test_newerXY_base() {
6771         local x=$1
6772         local y=$2
6773         local dir=$DIR/$tdir
6774         local ref
6775         local negref
6776
6777         if [ $y == "t" ]; then
6778                 if [ $x == "b" ]; then
6779                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6780                 else
6781                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6782                 fi
6783         else
6784                 ref=$DIR/$tfile.newer.$x$y
6785                 touch $ref || error "touch $ref failed"
6786         fi
6787
6788         echo "before = $ref"
6789         sleep 2
6790         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6791         sleep 2
6792         if [ $y == "t" ]; then
6793                 if [ $x == "b" ]; then
6794                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6795                 else
6796                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6797                 fi
6798         else
6799                 negref=$DIR/$tfile.negnewer.$x$y
6800                 touch $negref || error "touch $negref failed"
6801         fi
6802
6803         echo "after = $negref"
6804         local cmd="$LFS find $dir -newer$x$y $ref"
6805         local nums=$(eval $cmd | wc -l)
6806         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6807
6808         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6809                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6810
6811         cmd="$LFS find $dir ! -newer$x$y $negref"
6812         nums=$(eval $cmd | wc -l)
6813         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6814                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6815
6816         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6817         nums=$(eval $cmd | wc -l)
6818         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6819                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6820
6821         rm -rf $DIR/*
6822 }
6823
6824 test_56oc() {
6825         test_newerXY_base "a" "a"
6826         test_newerXY_base "a" "m"
6827         test_newerXY_base "a" "c"
6828         test_newerXY_base "m" "a"
6829         test_newerXY_base "m" "m"
6830         test_newerXY_base "m" "c"
6831         test_newerXY_base "c" "a"
6832         test_newerXY_base "c" "m"
6833         test_newerXY_base "c" "c"
6834
6835         test_newerXY_base "a" "t"
6836         test_newerXY_base "m" "t"
6837         test_newerXY_base "c" "t"
6838
6839         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6840            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6841                 ! btime_supported && echo "btime unsupported" && return 0
6842
6843         test_newerXY_base "b" "b"
6844         test_newerXY_base "b" "t"
6845 }
6846 run_test 56oc "check lfs find -newerXY work"
6847
6848 btime_supported() {
6849         local dir=$DIR/$tdir
6850         local rc
6851
6852         mkdir -p $dir
6853         touch $dir/$tfile
6854         $LFS find $dir -btime -1d -type f
6855         rc=$?
6856         rm -rf $dir
6857         return $rc
6858 }
6859
6860 test_56od() {
6861         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6862                 ! btime_supported && skip "btime unsupported on MDS"
6863
6864         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6865                 ! btime_supported && skip "btime unsupported on clients"
6866
6867         local dir=$DIR/$tdir
6868         local ref=$DIR/$tfile.ref
6869         local negref=$DIR/$tfile.negref
6870
6871         mkdir $dir || error "mkdir $dir failed"
6872         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6873         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6874         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6875         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6876         touch $ref || error "touch $ref failed"
6877         # sleep 3 seconds at least
6878         sleep 3
6879
6880         local before=$(do_facet mds1 date +%s)
6881         local skew=$(($(date +%s) - before + 1))
6882
6883         if (( skew < 0 && skew > -5 )); then
6884                 sleep $((0 - skew + 1))
6885                 skew=0
6886         fi
6887
6888         # Set the dir stripe params to limit files all on MDT0,
6889         # otherwise we need to calc the max clock skew between
6890         # the client and MDTs.
6891         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6892         sleep 2
6893         touch $negref || error "touch $negref failed"
6894
6895         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6896         local nums=$($cmd | wc -l)
6897         local expected=$(((NUMFILES + 1) * NUMDIRS))
6898
6899         [ $nums -eq $expected ] ||
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901
6902         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6903         nums=$($cmd | wc -l)
6904         expected=$((NUMFILES + 1))
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907
6908         [ $skew -lt 0 ] && return
6909
6910         local after=$(do_facet mds1 date +%s)
6911         local age=$((after - before + 1 + skew))
6912
6913         cmd="$LFS find $dir -btime -${age}s -type f"
6914         nums=$($cmd | wc -l)
6915         expected=$(((NUMFILES + 1) * NUMDIRS))
6916
6917         echo "Clock skew between client and server: $skew, age:$age"
6918         [ $nums -eq $expected ] ||
6919                 error "'$cmd' wrong: found $nums, expected $expected"
6920
6921         expected=$(($NUMDIRS + 1))
6922         cmd="$LFS find $dir -btime -${age}s -type d"
6923         nums=$($cmd | wc -l)
6924         [ $nums -eq $expected ] ||
6925                 error "'$cmd' wrong: found $nums, expected $expected"
6926         rm -f $ref $negref || error "Failed to remove $ref $negref"
6927 }
6928 run_test 56od "check lfs find -btime with units"
6929
6930 test_56p() {
6931         [ $RUNAS_ID -eq $UID ] &&
6932                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6933
6934         local dir=$DIR/$tdir
6935
6936         setup_56 $dir $NUMFILES $NUMDIRS
6937         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6938
6939         local expected=$NUMFILES
6940         local cmd="$LFS find -uid $RUNAS_ID $dir"
6941         local nums=$($cmd | wc -l)
6942
6943         [ $nums -eq $expected ] ||
6944                 error "'$cmd' wrong: found $nums, expected $expected"
6945
6946         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6947         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6948         nums=$($cmd | wc -l)
6949         [ $nums -eq $expected ] ||
6950                 error "'$cmd' wrong: found $nums, expected $expected"
6951 }
6952 run_test 56p "check lfs find -uid and ! -uid"
6953
6954 test_56q() {
6955         [ $RUNAS_ID -eq $UID ] &&
6956                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6957
6958         local dir=$DIR/$tdir
6959
6960         setup_56 $dir $NUMFILES $NUMDIRS
6961         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6962
6963         local expected=$NUMFILES
6964         local cmd="$LFS find -gid $RUNAS_GID $dir"
6965         local nums=$($cmd | wc -l)
6966
6967         [ $nums -eq $expected ] ||
6968                 error "'$cmd' wrong: found $nums, expected $expected"
6969
6970         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6971         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6972         nums=$($cmd | wc -l)
6973         [ $nums -eq $expected ] ||
6974                 error "'$cmd' wrong: found $nums, expected $expected"
6975 }
6976 run_test 56q "check lfs find -gid and ! -gid"
6977
6978 test_56r() {
6979         local dir=$DIR/$tdir
6980
6981         setup_56 $dir $NUMFILES $NUMDIRS
6982
6983         local expected=12
6984         local cmd="$LFS find -size 0 -type f -lazy $dir"
6985         local nums=$($cmd | wc -l)
6986
6987         [ $nums -eq $expected ] ||
6988                 error "'$cmd' wrong: found $nums, expected $expected"
6989         cmd="$LFS find -size 0 -type f $dir"
6990         nums=$($cmd | wc -l)
6991         [ $nums -eq $expected ] ||
6992                 error "'$cmd' wrong: found $nums, expected $expected"
6993
6994         expected=0
6995         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6996         nums=$($cmd | wc -l)
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999         cmd="$LFS find ! -size 0 -type f $dir"
7000         nums=$($cmd | wc -l)
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         echo "test" > $dir/$tfile
7005         echo "test2" > $dir/$tfile.2 && sync
7006         expected=1
7007         cmd="$LFS find -size 5 -type f -lazy $dir"
7008         nums=$($cmd | wc -l)
7009         [ $nums -eq $expected ] ||
7010                 error "'$cmd' wrong: found $nums, expected $expected"
7011         cmd="$LFS find -size 5 -type f $dir"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015
7016         expected=1
7017         cmd="$LFS find -size +5 -type f -lazy $dir"
7018         nums=$($cmd | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021         cmd="$LFS find -size +5 -type f $dir"
7022         nums=$($cmd | wc -l)
7023         [ $nums -eq $expected ] ||
7024                 error "'$cmd' wrong: found $nums, expected $expected"
7025
7026         expected=2
7027         cmd="$LFS find -size +0 -type f -lazy $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031         cmd="$LFS find -size +0 -type f $dir"
7032         nums=$($cmd | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         expected=2
7037         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041         cmd="$LFS find ! -size -5 -type f $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045
7046         expected=12
7047         cmd="$LFS find -size -5 -type f -lazy $dir"
7048         nums=$($cmd | wc -l)
7049         [ $nums -eq $expected ] ||
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051         cmd="$LFS find -size -5 -type f $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055 }
7056 run_test 56r "check lfs find -size works"
7057
7058 test_56ra_sub() {
7059         local expected=$1
7060         local glimpses=$2
7061         local cmd="$3"
7062
7063         cancel_lru_locks $OSC
7064
7065         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7066         local nums=$($cmd | wc -l)
7067
7068         [ $nums -eq $expected ] ||
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070
7071         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7072
7073         if (( rpcs_before + glimpses != rpcs_after )); then
7074                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7075                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7076
7077                 if [[ $glimpses == 0 ]]; then
7078                         error "'$cmd' should not send glimpse RPCs to OST"
7079                 else
7080                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7081                 fi
7082         fi
7083 }
7084
7085 test_56ra() {
7086         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7087                 skip "MDS < 2.12.58 doesn't return LSOM data"
7088         local dir=$DIR/$tdir
7089         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7090
7091         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7092
7093         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7094         $LCTL set_param -n llite.*.statahead_agl=0
7095         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7096
7097         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7098         # open and close all files to ensure LSOM is updated
7099         cancel_lru_locks $OSC
7100         find $dir -type f | xargs cat > /dev/null
7101
7102         #   expect_found  glimpse_rpcs  command_to_run
7103         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7104         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7105         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7106         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7107
7108         echo "test" > $dir/$tfile
7109         echo "test2" > $dir/$tfile.2 && sync
7110         cancel_lru_locks $OSC
7111         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7112
7113         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7114         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7115         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7116         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7117
7118         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7119         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7120         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7121         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7122         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7123         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7124 }
7125 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7126
7127 test_56rb() {
7128         local dir=$DIR/$tdir
7129         local tmp=$TMP/$tfile.log
7130         local mdt_idx;
7131
7132         test_mkdir -p $dir || error "failed to mkdir $dir"
7133         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7134                 error "failed to setstripe $dir/$tfile"
7135         mdt_idx=$($LFS getdirstripe -i $dir)
7136         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7137
7138         stack_trap "rm -f $tmp" EXIT
7139         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7140         ! grep -q obd_uuid $tmp ||
7141                 error "failed to find --size +100K --ost 0 $dir"
7142         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7143         ! grep -q obd_uuid $tmp ||
7144                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7145 }
7146 run_test 56rb "check lfs find --size --ost/--mdt works"
7147
7148 test_56rc() {
7149         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7150         local dir=$DIR/$tdir
7151         local found
7152
7153         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7154         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7155         (( $MDSCOUNT > 2 )) &&
7156                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7157         mkdir $dir/$tdir-{1..10}
7158         touch $dir/$tfile-{1..10}
7159
7160         found=$($LFS find $dir --mdt-count 2 | wc -l)
7161         expect=11
7162         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7163
7164         found=$($LFS find $dir -T +1 | wc -l)
7165         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7166         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7167
7168         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7169         expect=11
7170         (( $found == $expect )) || error "found $found all_char, expect $expect"
7171
7172         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7173         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7174         (( $found == $expect )) || error "found $found all_char, expect $expect"
7175 }
7176 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7177
7178 test_56s() { # LU-611 #LU-9369
7179         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7180
7181         local dir=$DIR/$tdir
7182         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7183
7184         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7185         for i in $(seq $NUMDIRS); do
7186                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7187         done
7188
7189         local expected=$NUMDIRS
7190         local cmd="$LFS find -c $OSTCOUNT $dir"
7191         local nums=$($cmd | wc -l)
7192
7193         [ $nums -eq $expected ] || {
7194                 $LFS getstripe -R $dir
7195                 error "'$cmd' wrong: found $nums, expected $expected"
7196         }
7197
7198         expected=$((NUMDIRS + onestripe))
7199         cmd="$LFS find -stripe-count +0 -type f $dir"
7200         nums=$($cmd | wc -l)
7201         [ $nums -eq $expected ] || {
7202                 $LFS getstripe -R $dir
7203                 error "'$cmd' wrong: found $nums, expected $expected"
7204         }
7205
7206         expected=$onestripe
7207         cmd="$LFS find -stripe-count 1 -type f $dir"
7208         nums=$($cmd | wc -l)
7209         [ $nums -eq $expected ] || {
7210                 $LFS getstripe -R $dir
7211                 error "'$cmd' wrong: found $nums, expected $expected"
7212         }
7213
7214         cmd="$LFS find -stripe-count -2 -type f $dir"
7215         nums=$($cmd | wc -l)
7216         [ $nums -eq $expected ] || {
7217                 $LFS getstripe -R $dir
7218                 error "'$cmd' wrong: found $nums, expected $expected"
7219         }
7220
7221         expected=0
7222         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7223         nums=$($cmd | wc -l)
7224         [ $nums -eq $expected ] || {
7225                 $LFS getstripe -R $dir
7226                 error "'$cmd' wrong: found $nums, expected $expected"
7227         }
7228 }
7229 run_test 56s "check lfs find -stripe-count works"
7230
7231 test_56t() { # LU-611 #LU-9369
7232         local dir=$DIR/$tdir
7233
7234         setup_56 $dir 0 $NUMDIRS
7235         for i in $(seq $NUMDIRS); do
7236                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7237         done
7238
7239         local expected=$NUMDIRS
7240         local cmd="$LFS find -S 8M $dir"
7241         local nums=$($cmd | wc -l)
7242
7243         [ $nums -eq $expected ] || {
7244                 $LFS getstripe -R $dir
7245                 error "'$cmd' wrong: found $nums, expected $expected"
7246         }
7247         rm -rf $dir
7248
7249         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7250
7251         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7252
7253         expected=$(((NUMDIRS + 1) * NUMFILES))
7254         cmd="$LFS find -stripe-size 512k -type f $dir"
7255         nums=$($cmd | wc -l)
7256         [ $nums -eq $expected ] ||
7257                 error "'$cmd' wrong: found $nums, expected $expected"
7258
7259         cmd="$LFS find -stripe-size +320k -type f $dir"
7260         nums=$($cmd | wc -l)
7261         [ $nums -eq $expected ] ||
7262                 error "'$cmd' wrong: found $nums, expected $expected"
7263
7264         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7265         cmd="$LFS find -stripe-size +200k -type f $dir"
7266         nums=$($cmd | wc -l)
7267         [ $nums -eq $expected ] ||
7268                 error "'$cmd' wrong: found $nums, expected $expected"
7269
7270         cmd="$LFS find -stripe-size -640k -type f $dir"
7271         nums=$($cmd | wc -l)
7272         [ $nums -eq $expected ] ||
7273                 error "'$cmd' wrong: found $nums, expected $expected"
7274
7275         expected=4
7276         cmd="$LFS find -stripe-size 256k -type f $dir"
7277         nums=$($cmd | wc -l)
7278         [ $nums -eq $expected ] ||
7279                 error "'$cmd' wrong: found $nums, expected $expected"
7280
7281         cmd="$LFS find -stripe-size -320k -type f $dir"
7282         nums=$($cmd | wc -l)
7283         [ $nums -eq $expected ] ||
7284                 error "'$cmd' wrong: found $nums, expected $expected"
7285
7286         expected=0
7287         cmd="$LFS find -stripe-size 1024k -type f $dir"
7288         nums=$($cmd | wc -l)
7289         [ $nums -eq $expected ] ||
7290                 error "'$cmd' wrong: found $nums, expected $expected"
7291 }
7292 run_test 56t "check lfs find -stripe-size works"
7293
7294 test_56u() { # LU-611
7295         local dir=$DIR/$tdir
7296
7297         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7298
7299         if [[ $OSTCOUNT -gt 1 ]]; then
7300                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7301                 onestripe=4
7302         else
7303                 onestripe=0
7304         fi
7305
7306         local expected=$(((NUMDIRS + 1) * NUMFILES))
7307         local cmd="$LFS find -stripe-index 0 -type f $dir"
7308         local nums=$($cmd | wc -l)
7309
7310         [ $nums -eq $expected ] ||
7311                 error "'$cmd' wrong: found $nums, expected $expected"
7312
7313         expected=$onestripe
7314         cmd="$LFS find -stripe-index 1 -type f $dir"
7315         nums=$($cmd | wc -l)
7316         [ $nums -eq $expected ] ||
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318
7319         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7320         nums=$($cmd | wc -l)
7321         [ $nums -eq $expected ] ||
7322                 error "'$cmd' wrong: found $nums, expected $expected"
7323
7324         expected=0
7325         # This should produce an error and not return any files
7326         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7327         nums=$($cmd 2>/dev/null | wc -l)
7328         [ $nums -eq $expected ] ||
7329                 error "'$cmd' wrong: found $nums, expected $expected"
7330
7331         if [[ $OSTCOUNT -gt 1 ]]; then
7332                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7333                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7334                 nums=$($cmd | wc -l)
7335                 [ $nums -eq $expected ] ||
7336                         error "'$cmd' wrong: found $nums, expected $expected"
7337         fi
7338 }
7339 run_test 56u "check lfs find -stripe-index works"
7340
7341 test_56v() {
7342         local mdt_idx=0
7343         local dir=$DIR/$tdir
7344
7345         setup_56 $dir $NUMFILES $NUMDIRS
7346
7347         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7348         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7349
7350         for file in $($LFS find -m $UUID $dir); do
7351                 file_midx=$($LFS getstripe -m $file)
7352                 [ $file_midx -eq $mdt_idx ] ||
7353                         error "lfs find -m $UUID != getstripe -m $file_midx"
7354         done
7355 }
7356 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7357
7358 test_56wa() {
7359         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7361
7362         local dir=$DIR/$tdir
7363
7364         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7365
7366         local stripe_size=$($LFS getstripe -S -d $dir) ||
7367                 error "$LFS getstripe -S -d $dir failed"
7368         stripe_size=${stripe_size%% *}
7369
7370         local file_size=$((stripe_size * OSTCOUNT))
7371         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7372         local required_space=$((file_num * file_size))
7373         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7374                            head -n1)
7375         (( free_space >= required_space / 1024 )) ||
7376                 skip_env "need $required_space, have $free_space kbytes"
7377
7378         local dd_bs=65536
7379         local dd_count=$((file_size / dd_bs))
7380
7381         # write data into the files
7382         local i
7383         local j
7384         local file
7385
7386         for ((i = 1; i <= NUMFILES; i++ )); do
7387                 file=$dir/file$i
7388                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7389                         error "write data into $file failed"
7390         done
7391         for ((i = 1; i <= NUMDIRS; i++ )); do
7392                 for ((j = 1; j <= NUMFILES; j++ )); do
7393                         file=$dir/dir$i/file$j
7394                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7395                                 error "write data into $file failed"
7396                 done
7397         done
7398
7399         # $LFS_MIGRATE will fail if hard link migration is unsupported
7400         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7401                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7402                         error "creating links to $dir/dir1/file1 failed"
7403         fi
7404
7405         local expected=-1
7406
7407         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7408
7409         # lfs_migrate file
7410         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7411
7412         echo "$cmd"
7413         eval $cmd || error "$cmd failed"
7414
7415         check_stripe_count $dir/file1 $expected
7416
7417         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7418                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7419                 # OST 1 if it is on OST 0. This file is small enough to
7420                 # be on only one stripe.
7421                 file=$dir/migr_1_ost
7422                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7423                         error "write data into $file failed"
7424                 local obdidx=$($LFS getstripe -i $file)
7425                 local oldmd5=$(md5sum $file)
7426                 local newobdidx=0
7427
7428                 (( obdidx != 0 )) || newobdidx=1
7429                 cmd="$LFS migrate -i $newobdidx $file"
7430                 echo $cmd
7431                 eval $cmd || error "$cmd failed"
7432
7433                 local realobdix=$($LFS getstripe -i $file)
7434                 local newmd5=$(md5sum $file)
7435
7436                 (( $newobdidx == $realobdix )) ||
7437                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7438                 [[ "$oldmd5" == "$newmd5" ]] ||
7439                         error "md5sum differ: $oldmd5, $newmd5"
7440         fi
7441
7442         # lfs_migrate dir
7443         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7444         echo "$cmd"
7445         eval $cmd || error "$cmd failed"
7446
7447         for (( j = 1; j <= NUMFILES; j++ )); do
7448                 check_stripe_count $dir/dir1/file$j $expected
7449         done
7450
7451         # lfs_migrate works with lfs find
7452         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7453              $LFS_MIGRATE -y -c $expected"
7454         echo "$cmd"
7455         eval $cmd || error "$cmd failed"
7456
7457         for (( i = 2; i <= NUMFILES; i++ )); do
7458                 check_stripe_count $dir/file$i $expected
7459         done
7460         for (( i = 2; i <= NUMDIRS; i++ )); do
7461                 for (( j = 1; j <= NUMFILES; j++ )); do
7462                         check_stripe_count $dir/dir$i/file$j $expected
7463                 done
7464         done
7465 }
7466 run_test 56wa "check lfs_migrate -c stripe_count works"
7467
7468 test_56wb() {
7469         local file1=$DIR/$tdir/file1
7470         local create_pool=false
7471         local initial_pool=$($LFS getstripe -p $DIR)
7472         local pool_list=()
7473         local pool=""
7474
7475         echo -n "Creating test dir..."
7476         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7477         echo "done."
7478
7479         echo -n "Creating test file..."
7480         touch $file1 || error "cannot create file"
7481         echo "done."
7482
7483         echo -n "Detecting existing pools..."
7484         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7485
7486         if [ ${#pool_list[@]} -gt 0 ]; then
7487                 echo "${pool_list[@]}"
7488                 for thispool in "${pool_list[@]}"; do
7489                         if [[ -z "$initial_pool" ||
7490                               "$initial_pool" != "$thispool" ]]; then
7491                                 pool="$thispool"
7492                                 echo "Using existing pool '$pool'"
7493                                 break
7494                         fi
7495                 done
7496         else
7497                 echo "none detected."
7498         fi
7499         if [ -z "$pool" ]; then
7500                 pool=${POOL:-testpool}
7501                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7502                 echo -n "Creating pool '$pool'..."
7503                 create_pool=true
7504                 pool_add $pool &> /dev/null ||
7505                         error "pool_add failed"
7506                 echo "done."
7507
7508                 echo -n "Adding target to pool..."
7509                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7510                         error "pool_add_targets failed"
7511                 echo "done."
7512         fi
7513
7514         echo -n "Setting pool using -p option..."
7515         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7516                 error "migrate failed rc = $?"
7517         echo "done."
7518
7519         echo -n "Verifying test file is in pool after migrating..."
7520         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7521                 error "file was not migrated to pool $pool"
7522         echo "done."
7523
7524         echo -n "Removing test file from pool '$pool'..."
7525         # "lfs migrate $file" won't remove the file from the pool
7526         # until some striping information is changed.
7527         $LFS migrate -c 1 $file1 &> /dev/null ||
7528                 error "cannot remove from pool"
7529         [ "$($LFS getstripe -p $file1)" ] &&
7530                 error "pool still set"
7531         echo "done."
7532
7533         echo -n "Setting pool using --pool option..."
7534         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7535                 error "migrate failed rc = $?"
7536         echo "done."
7537
7538         # Clean up
7539         rm -f $file1
7540         if $create_pool; then
7541                 destroy_test_pools 2> /dev/null ||
7542                         error "destroy test pools failed"
7543         fi
7544 }
7545 run_test 56wb "check lfs_migrate pool support"
7546
7547 test_56wc() {
7548         local file1="$DIR/$tdir/$tfile"
7549         local md5
7550         local parent_ssize
7551         local parent_scount
7552         local cur_ssize
7553         local cur_scount
7554         local orig_ssize
7555         local new_scount
7556         local cur_comp
7557
7558         echo -n "Creating test dir..."
7559         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7560         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7561                 error "cannot set stripe by '-S 1M -c 1'"
7562         echo "done"
7563
7564         echo -n "Setting initial stripe for test file..."
7565         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7566                 error "cannot set stripe"
7567         cur_ssize=$($LFS getstripe -S "$file1")
7568         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7569         echo "done."
7570
7571         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7572         stack_trap "rm -f $file1"
7573         md5="$(md5sum $file1)"
7574
7575         # File currently set to -S 512K -c 1
7576
7577         # Ensure -c and -S options are rejected when -R is set
7578         echo -n "Verifying incompatible options are detected..."
7579         $LFS_MIGRATE -R -c 1 "$file1" &&
7580                 error "incompatible -R and -c options not detected"
7581         $LFS_MIGRATE -R -S 1M "$file1" &&
7582                 error "incompatible -R and -S options not detected"
7583         $LFS_MIGRATE -R -p pool "$file1" &&
7584                 error "incompatible -R and -p options not detected"
7585         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7586                 error "incompatible -R and -E options not detected"
7587         $LFS_MIGRATE -R -A "$file1" &&
7588                 error "incompatible -R and -A options not detected"
7589         $LFS_MIGRATE -A -c 1 "$file1" &&
7590                 error "incompatible -A and -c options not detected"
7591         $LFS_MIGRATE -A -S 1M "$file1" &&
7592                 error "incompatible -A and -S options not detected"
7593         $LFS_MIGRATE -A -p pool "$file1" &&
7594                 error "incompatible -A and -p options not detected"
7595         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7596                 error "incompatible -A and -E options not detected"
7597         echo "done."
7598
7599         # Ensure unrecognized options are passed through to 'lfs migrate'
7600         echo -n "Verifying -S option is passed through to lfs migrate..."
7601         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7602         cur_ssize=$($LFS getstripe -S "$file1")
7603         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7604         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7605         echo "done."
7606
7607         # File currently set to -S 1M -c 1
7608
7609         # Ensure long options are supported
7610         echo -n "Verifying long options supported..."
7611         $LFS_MIGRATE --non-block "$file1" ||
7612                 error "long option without argument not supported"
7613         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7614                 error "long option with argument not supported"
7615         cur_ssize=$($LFS getstripe -S "$file1")
7616         (( cur_ssize == 524288 )) ||
7617                 error "migrate --stripe-size $cur_ssize != 524288"
7618         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7619         echo "done."
7620
7621         # File currently set to -S 512K -c 1
7622
7623         if (( OSTCOUNT > 1 )); then
7624                 echo -n "Verifying explicit stripe count can be set..."
7625                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7626                 cur_scount=$($LFS getstripe -c "$file1")
7627                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7628                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7629                         error "file data has changed (3)"
7630                 echo "done."
7631         fi
7632
7633         # File currently set to -S 512K -c 1 or -S 512K -c 2
7634
7635         # Ensure parent striping is used if -R is set, and no stripe
7636         # count or size is specified
7637         echo -n "Setting stripe for parent directory..."
7638         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7639                 error "cannot set stripe '-S 2M -c 1'"
7640         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7641         echo "done."
7642
7643         echo -n "Verifying restripe option uses parent stripe settings..."
7644         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7645         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7646         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7647         cur_ssize=$($LFS getstripe -S "$file1")
7648         (( cur_ssize == parent_ssize )) ||
7649                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7650         cur_scount=$($LFS getstripe -c "$file1")
7651         (( cur_scount == parent_scount )) ||
7652                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7653         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7654         echo "done."
7655
7656         # File currently set to -S 1M -c 1
7657
7658         # Ensure striping is preserved if -R is not set, and no stripe
7659         # count or size is specified
7660         echo -n "Verifying striping size preserved when not specified..."
7661         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7662         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7663                 error "cannot set stripe on parent directory"
7664         $LFS_MIGRATE "$file1" || error "migrate failed"
7665         cur_ssize=$($LFS getstripe -S "$file1")
7666         (( cur_ssize == orig_ssize )) ||
7667                 error "migrate by default $cur_ssize != $orig_ssize"
7668         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7669         echo "done."
7670
7671         # Ensure file name properly detected when final option has no argument
7672         echo -n "Verifying file name properly detected..."
7673         $LFS_MIGRATE "$file1" ||
7674                 error "file name interpreted as option argument"
7675         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7676         echo "done."
7677
7678         # Ensure PFL arguments are passed through properly
7679         echo -n "Verifying PFL options passed through..."
7680         new_scount=$(((OSTCOUNT + 1) / 2))
7681         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7682                 error "migrate PFL arguments failed"
7683         cur_comp=$($LFS getstripe --comp-count $file1)
7684         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7685         cur_scount=$($LFS getstripe --stripe-count $file1)
7686         (( cur_scount == new_scount)) ||
7687                 error "PFL stripe count $cur_scount != $new_scount"
7688         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7689         echo "done."
7690 }
7691 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7692
7693 test_56wd() {
7694         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7695
7696         local file1=$DIR/$tdir/$tfile
7697
7698         echo -n "Creating test dir..."
7699         test_mkdir $DIR/$tdir || error "cannot create dir"
7700         echo "done."
7701
7702         echo -n "Creating test file..."
7703         echo "$tfile" > $file1
7704         echo "done."
7705
7706         # Ensure 'lfs migrate' will fail by using a non-existent option,
7707         # and make sure rsync is not called to recover
7708         echo -n "Make sure --no-rsync option works..."
7709         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7710                 grep -q 'refusing to fall back to rsync' ||
7711                 error "rsync was called with --no-rsync set"
7712         echo "done."
7713
7714         # Ensure rsync is called without trying 'lfs migrate' first
7715         echo -n "Make sure --rsync option works..."
7716         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7717                 grep -q 'falling back to rsync' &&
7718                 error "lfs migrate was called with --rsync set"
7719         echo "done."
7720 }
7721 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7722
7723 test_56we() {
7724         local td=$DIR/$tdir
7725         local tf=$td/$tfile
7726
7727         test_mkdir $td || error "cannot create $td"
7728         touch $tf || error "cannot touch $tf"
7729
7730         echo -n "Make sure --non-direct|-D works..."
7731         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7732                 grep -q "lfs migrate --non-direct" ||
7733                 error "--non-direct option cannot work correctly"
7734         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7735                 grep -q "lfs migrate -D" ||
7736                 error "-D option cannot work correctly"
7737         echo "done."
7738 }
7739 run_test 56we "check lfs_migrate --non-direct|-D support"
7740
7741 test_56x() {
7742         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7743         check_swap_layouts_support
7744
7745         local dir=$DIR/$tdir
7746         local ref1=/etc/passwd
7747         local file1=$dir/file1
7748
7749         test_mkdir $dir || error "creating dir $dir"
7750         $LFS setstripe -c 2 $file1
7751         cp $ref1 $file1
7752         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7753         stripe=$($LFS getstripe -c $file1)
7754         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7755         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7756
7757         # clean up
7758         rm -f $file1
7759 }
7760 run_test 56x "lfs migration support"
7761
7762 test_56xa() {
7763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7764         check_swap_layouts_support
7765
7766         local dir=$DIR/$tdir/$testnum
7767
7768         test_mkdir -p $dir
7769
7770         local ref1=/etc/passwd
7771         local file1=$dir/file1
7772
7773         $LFS setstripe -c 2 $file1
7774         cp $ref1 $file1
7775         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7776
7777         local stripe=$($LFS getstripe -c $file1)
7778
7779         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7780         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7781
7782         # clean up
7783         rm -f $file1
7784 }
7785 run_test 56xa "lfs migration --block support"
7786
7787 check_migrate_links() {
7788         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7789         local dir="$1"
7790         local file1="$dir/file1"
7791         local begin="$2"
7792         local count="$3"
7793         local runas="$4"
7794         local total_count=$(($begin + $count - 1))
7795         local symlink_count=10
7796         local uniq_count=10
7797
7798         if [ ! -f "$file1" ]; then
7799                 echo -n "creating initial file..."
7800                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7801                         error "cannot setstripe initial file"
7802                 echo "done"
7803
7804                 echo -n "creating symlinks..."
7805                 for s in $(seq 1 $symlink_count); do
7806                         ln -s "$file1" "$dir/slink$s" ||
7807                                 error "cannot create symlinks"
7808                 done
7809                 echo "done"
7810
7811                 echo -n "creating nonlinked files..."
7812                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7813                         error "cannot create nonlinked files"
7814                 echo "done"
7815         fi
7816
7817         # create hard links
7818         if [ ! -f "$dir/file$total_count" ]; then
7819                 echo -n "creating hard links $begin:$total_count..."
7820                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7821                         /dev/null || error "cannot create hard links"
7822                 echo "done"
7823         fi
7824
7825         echo -n "checking number of hard links listed in xattrs..."
7826         local fid=$($LFS getstripe -F "$file1")
7827         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7828
7829         echo "${#paths[*]}"
7830         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7831                         skip "hard link list has unexpected size, skipping test"
7832         fi
7833         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7834                         error "link names should exceed xattrs size"
7835         fi
7836
7837         echo -n "migrating files..."
7838         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7839         local rc=$?
7840         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7841         echo "done"
7842
7843         # make sure all links have been properly migrated
7844         echo -n "verifying files..."
7845         fid=$($LFS getstripe -F "$file1") ||
7846                 error "cannot get fid for file $file1"
7847         for i in $(seq 2 $total_count); do
7848                 local fid2=$($LFS getstripe -F $dir/file$i)
7849
7850                 [ "$fid2" == "$fid" ] ||
7851                         error "migrated hard link has mismatched FID"
7852         done
7853
7854         # make sure hard links were properly detected, and migration was
7855         # performed only once for the entire link set; nonlinked files should
7856         # also be migrated
7857         local actual=$(grep -c 'done' <<< "$migrate_out")
7858         local expected=$(($uniq_count + 1))
7859
7860         [ "$actual" -eq  "$expected" ] ||
7861                 error "hard links individually migrated ($actual != $expected)"
7862
7863         # make sure the correct number of hard links are present
7864         local hardlinks=$(stat -c '%h' "$file1")
7865
7866         [ $hardlinks -eq $total_count ] ||
7867                 error "num hard links $hardlinks != $total_count"
7868         echo "done"
7869
7870         return 0
7871 }
7872
7873 test_56xb() {
7874         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7875                 skip "Need MDS version at least 2.10.55"
7876
7877         local dir="$DIR/$tdir"
7878
7879         test_mkdir "$dir" || error "cannot create dir $dir"
7880
7881         echo "testing lfs migrate mode when all links fit within xattrs"
7882         check_migrate_links "$dir" 2 99
7883
7884         echo "testing rsync mode when all links fit within xattrs"
7885         check_migrate_links --rsync "$dir" 2 99
7886
7887         echo "testing lfs migrate mode when all links do not fit within xattrs"
7888         check_migrate_links "$dir" 101 100
7889
7890         echo "testing rsync mode when all links do not fit within xattrs"
7891         check_migrate_links --rsync "$dir" 101 100
7892
7893         chown -R $RUNAS_ID $dir
7894         echo "testing non-root lfs migrate mode when not all links are in xattr"
7895         check_migrate_links "$dir" 101 100 "$RUNAS"
7896
7897         # clean up
7898         rm -rf $dir
7899 }
7900 run_test 56xb "lfs migration hard link support"
7901
7902 test_56xc() {
7903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7904
7905         local dir="$DIR/$tdir"
7906
7907         test_mkdir "$dir" || error "cannot create dir $dir"
7908
7909         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7910         echo -n "Setting initial stripe for 20MB test file..."
7911         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7912                 error "cannot setstripe 20MB file"
7913         echo "done"
7914         echo -n "Sizing 20MB test file..."
7915         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7916         echo "done"
7917         echo -n "Verifying small file autostripe count is 1..."
7918         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7919                 error "cannot migrate 20MB file"
7920         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7921                 error "cannot get stripe for $dir/20mb"
7922         [ $stripe_count -eq 1 ] ||
7923                 error "unexpected stripe count $stripe_count for 20MB file"
7924         rm -f "$dir/20mb"
7925         echo "done"
7926
7927         # Test 2: File is small enough to fit within the available space on
7928         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7929         # have at least an additional 1KB for each desired stripe for test 3
7930         echo -n "Setting stripe for 1GB test file..."
7931         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7932         echo "done"
7933         echo -n "Sizing 1GB test file..."
7934         # File size is 1GB + 3KB
7935         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7936         echo "done"
7937
7938         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7939         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7940         if (( avail > 524288 * OSTCOUNT )); then
7941                 echo -n "Migrating 1GB file..."
7942                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7943                         error "cannot migrate 1GB file"
7944                 echo "done"
7945                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7946                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7947                         error "cannot getstripe for 1GB file"
7948                 [ $stripe_count -eq 2 ] ||
7949                         error "unexpected stripe count $stripe_count != 2"
7950                 echo "done"
7951         fi
7952
7953         # Test 3: File is too large to fit within the available space on
7954         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7955         if [ $OSTCOUNT -ge 3 ]; then
7956                 # The required available space is calculated as
7957                 # file size (1GB + 3KB) / OST count (3).
7958                 local kb_per_ost=349526
7959
7960                 echo -n "Migrating 1GB file with limit..."
7961                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7962                         error "cannot migrate 1GB file with limit"
7963                 echo "done"
7964
7965                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7966                 echo -n "Verifying 1GB autostripe count with limited space..."
7967                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7968                         error "unexpected stripe count $stripe_count (min 3)"
7969                 echo "done"
7970         fi
7971
7972         # clean up
7973         rm -rf $dir
7974 }
7975 run_test 56xc "lfs migration autostripe"
7976
7977 test_56xd() {
7978         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7979
7980         local dir=$DIR/$tdir
7981         local f_mgrt=$dir/$tfile.mgrt
7982         local f_yaml=$dir/$tfile.yaml
7983         local f_copy=$dir/$tfile.copy
7984         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7985         local layout_copy="-c 2 -S 2M -i 1"
7986         local yamlfile=$dir/yamlfile
7987         local layout_before;
7988         local layout_after;
7989
7990         test_mkdir "$dir" || error "cannot create dir $dir"
7991         $LFS setstripe $layout_yaml $f_yaml ||
7992                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7993         $LFS getstripe --yaml $f_yaml > $yamlfile
7994         $LFS setstripe $layout_copy $f_copy ||
7995                 error "cannot setstripe $f_copy with layout $layout_copy"
7996         touch $f_mgrt
7997         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7998
7999         # 1. test option --yaml
8000         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8001                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8002         layout_before=$(get_layout_param $f_yaml)
8003         layout_after=$(get_layout_param $f_mgrt)
8004         [ "$layout_after" == "$layout_before" ] ||
8005                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8006
8007         # 2. test option --copy
8008         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8009                 error "cannot migrate $f_mgrt with --copy $f_copy"
8010         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8011         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8012         [ "$layout_after" == "$layout_before" ] ||
8013                 error "lfs_migrate --copy: $layout_after != $layout_before"
8014 }
8015 run_test 56xd "check lfs_migrate --yaml and --copy support"
8016
8017 test_56xe() {
8018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8019
8020         local dir=$DIR/$tdir
8021         local f_comp=$dir/$tfile
8022         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8023         local layout_before=""
8024         local layout_after=""
8025
8026         test_mkdir "$dir" || error "cannot create dir $dir"
8027         $LFS setstripe $layout $f_comp ||
8028                 error "cannot setstripe $f_comp with layout $layout"
8029         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8030         dd if=/dev/zero of=$f_comp bs=1M count=4
8031
8032         # 1. migrate a comp layout file by lfs_migrate
8033         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8034         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8035         [ "$layout_before" == "$layout_after" ] ||
8036                 error "lfs_migrate: $layout_before != $layout_after"
8037
8038         # 2. migrate a comp layout file by lfs migrate
8039         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8040         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8041         [ "$layout_before" == "$layout_after" ] ||
8042                 error "lfs migrate: $layout_before != $layout_after"
8043 }
8044 run_test 56xe "migrate a composite layout file"
8045
8046 test_56xf() {
8047         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8048
8049         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8050                 skip "Need server version at least 2.13.53"
8051
8052         local dir=$DIR/$tdir
8053         local f_comp=$dir/$tfile
8054         local layout="-E 1M -c1 -E -1 -c2"
8055         local fid_before=""
8056         local fid_after=""
8057
8058         test_mkdir "$dir" || error "cannot create dir $dir"
8059         $LFS setstripe $layout $f_comp ||
8060                 error "cannot setstripe $f_comp with layout $layout"
8061         fid_before=$($LFS getstripe --fid $f_comp)
8062         dd if=/dev/zero of=$f_comp bs=1M count=4
8063
8064         # 1. migrate a comp layout file to a comp layout
8065         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8066         fid_after=$($LFS getstripe --fid $f_comp)
8067         [ "$fid_before" == "$fid_after" ] ||
8068                 error "comp-to-comp migrate: $fid_before != $fid_after"
8069
8070         # 2. migrate a comp layout file to a plain layout
8071         $LFS migrate -c2 $f_comp ||
8072                 error "cannot migrate $f_comp by lfs migrate"
8073         fid_after=$($LFS getstripe --fid $f_comp)
8074         [ "$fid_before" == "$fid_after" ] ||
8075                 error "comp-to-plain migrate: $fid_before != $fid_after"
8076
8077         # 3. migrate a plain layout file to a comp layout
8078         $LFS migrate $layout $f_comp ||
8079                 error "cannot migrate $f_comp by lfs migrate"
8080         fid_after=$($LFS getstripe --fid $f_comp)
8081         [ "$fid_before" == "$fid_after" ] ||
8082                 error "plain-to-comp migrate: $fid_before != $fid_after"
8083 }
8084 run_test 56xf "FID is not lost during migration of a composite layout file"
8085
8086 check_file_ost_range() {
8087         local file="$1"
8088         shift
8089         local range="$*"
8090         local -a file_range
8091         local idx
8092
8093         file_range=($($LFS getstripe -y "$file" |
8094                 awk '/l_ost_idx:/ { print $NF }'))
8095
8096         if [[ "${#file_range[@]}" = 0 ]]; then
8097                 echo "No osts found for $file"
8098                 return 1
8099         fi
8100
8101         for idx in "${file_range[@]}"; do
8102                 [[ " $range " =~ " $idx " ]] ||
8103                         return 1
8104         done
8105
8106         return 0
8107 }
8108
8109 sub_test_56xg() {
8110         local stripe_opt="$1"
8111         local pool="$2"
8112         shift 2
8113         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8114
8115         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8116                 error "Fail to migrate $tfile on $pool"
8117         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8118                 error "$tfile is not in pool $pool"
8119         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8120                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8121 }
8122
8123 test_56xg() {
8124         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8125         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8126         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8127                 skip "Need MDS version newer than 2.14.52"
8128
8129         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8130         local -a pool_ranges=("0 0" "1 1" "0 1")
8131
8132         # init pools
8133         for i in "${!pool_names[@]}"; do
8134                 pool_add ${pool_names[$i]} ||
8135                         error "pool_add failed (pool: ${pool_names[$i]})"
8136                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8137                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8138         done
8139
8140         # init the file to migrate
8141         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8142                 error "Unable to create $tfile on OST1"
8143         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8144                 error "Unable to write on $tfile"
8145
8146         echo "1. migrate $tfile on pool ${pool_names[0]}"
8147         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8148
8149         echo "2. migrate $tfile on pool ${pool_names[2]}"
8150         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8151
8152         echo "3. migrate $tfile on pool ${pool_names[1]}"
8153         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8154
8155         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8156         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8157         echo
8158
8159         # Clean pools
8160         destroy_test_pools ||
8161                 error "pool_destroy failed"
8162 }
8163 run_test 56xg "lfs migrate pool support"
8164
8165 test_56xh() {
8166         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8167
8168         local size_mb=25
8169         local file1=$DIR/$tfile
8170         local tmp1=$TMP/$tfile.tmp
8171
8172         $LFS setstripe -c 2 $file1
8173
8174         stack_trap "rm -f $file1 $tmp1"
8175         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8176                         error "error creating $tmp1"
8177         ls -lsh $tmp1
8178         cp $tmp1 $file1
8179
8180         local start=$SECONDS
8181
8182         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8183                 error "migrate failed rc = $?"
8184
8185         local elapsed=$((SECONDS - start))
8186
8187         # with 1MB/s, elapsed should equal size_mb
8188         (( elapsed >= size_mb * 95 / 100 )) ||
8189                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8190
8191         (( elapsed <= size_mb * 120 / 100 )) ||
8192                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8193
8194         (( elapsed <= size_mb * 350 / 100 )) ||
8195                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8196
8197         stripe=$($LFS getstripe -c $file1)
8198         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8199         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8200
8201         # Clean up file (since it is multiple MB)
8202         rm -f $file1 $tmp1
8203 }
8204 run_test 56xh "lfs migrate bandwidth limitation support"
8205
8206 test_56xi() {
8207         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8208         verify_yaml_available || skip_env "YAML verification not installed"
8209
8210         local size_mb=5
8211         local file1=$DIR/$tfile.1
8212         local file2=$DIR/$tfile.2
8213         local file3=$DIR/$tfile.3
8214         local output_file=$DIR/$tfile.out
8215         local tmp1=$TMP/$tfile.tmp
8216
8217         $LFS setstripe -c 2 $file1
8218         $LFS setstripe -c 2 $file2
8219         $LFS setstripe -c 2 $file3
8220
8221         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8222         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8223                         error "error creating $tmp1"
8224         ls -lsh $tmp1
8225         cp $tmp1 $file1
8226         cp $tmp1 $file2
8227         cp $tmp1 $file3
8228
8229         $LFS migrate --stats --stats-interval=1 \
8230                 -c 1 $file1 $file2 $file3 1> $output_file ||
8231                 error "migrate failed rc = $?"
8232
8233         cat $output_file
8234         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8235
8236         # Clean up file (since it is multiple MB)
8237         rm -f $file1 $file2 $file3 $tmp1 $output_file
8238 }
8239 run_test 56xi "lfs migrate stats support"
8240
8241 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8242         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8243
8244         local file=$DIR/$tfile
8245         local linkdir=$DIR/$tdir
8246
8247         test_mkdir $linkdir || error "fail to create $linkdir"
8248         $LFS setstripe -i 0 -c 1 -S1M $file
8249         dd if=/dev/urandom of=$file bs=1M count=10 ||
8250                 error "fail to create $file"
8251
8252         # Create file links
8253         local cpts
8254         local threads_max
8255         local nlinks
8256
8257         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8258         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8259         (( nlinks = thread_max * 3 / 2 / cpts))
8260
8261         echo "create $nlinks hard links of $file"
8262         createmany -l $file $linkdir/link $nlinks
8263
8264         # Parallel migrates (should not block)
8265         local i
8266         for ((i = 0; i < nlinks; i++)); do
8267                 echo $linkdir/link$i
8268         done | xargs -n1 -P $nlinks $LFS migrate -c2
8269
8270         local stripe_count
8271         stripe_count=$($LFS getstripe -c $file) ||
8272                 error "fail to get stripe count on $file"
8273
8274         ((stripe_count == 2)) ||
8275                 error "fail to migrate $file (stripe_count = $stripe_count)"
8276 }
8277 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8278
8279 test_56y() {
8280         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8281                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8282
8283         local res=""
8284         local dir=$DIR/$tdir
8285         local f1=$dir/file1
8286         local f2=$dir/file2
8287
8288         test_mkdir -p $dir || error "creating dir $dir"
8289         touch $f1 || error "creating std file $f1"
8290         $MULTIOP $f2 H2c || error "creating released file $f2"
8291
8292         # a directory can be raid0, so ask only for files
8293         res=$($LFS find $dir -L raid0 -type f | wc -l)
8294         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8295
8296         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8297         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8298
8299         # only files can be released, so no need to force file search
8300         res=$($LFS find $dir -L released)
8301         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8302
8303         res=$($LFS find $dir -type f \! -L released)
8304         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8305 }
8306 run_test 56y "lfs find -L raid0|released"
8307
8308 test_56z() { # LU-4824
8309         # This checks to make sure 'lfs find' continues after errors
8310         # There are two classes of errors that should be caught:
8311         # - If multiple paths are provided, all should be searched even if one
8312         #   errors out
8313         # - If errors are encountered during the search, it should not terminate
8314         #   early
8315         local dir=$DIR/$tdir
8316         local i
8317
8318         test_mkdir $dir
8319         for i in d{0..9}; do
8320                 test_mkdir $dir/$i
8321                 touch $dir/$i/$tfile
8322         done
8323         $LFS find $DIR/non_existent_dir $dir &&
8324                 error "$LFS find did not return an error"
8325         # Make a directory unsearchable. This should NOT be the last entry in
8326         # directory order.  Arbitrarily pick the 6th entry
8327         chmod 700 $($LFS find $dir -type d | sed '6!d')
8328
8329         $RUNAS $LFS find $DIR/non_existent $dir
8330         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8331
8332         # The user should be able to see 10 directories and 9 files
8333         (( count == 19 )) ||
8334                 error "$LFS find found $count != 19 entries after error"
8335 }
8336 run_test 56z "lfs find should continue after an error"
8337
8338 test_56aa() { # LU-5937
8339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8340
8341         local dir=$DIR/$tdir
8342
8343         mkdir $dir
8344         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8345
8346         createmany -o $dir/striped_dir/${tfile}- 1024
8347         local dirs=$($LFS find --size +8k $dir/)
8348
8349         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8350 }
8351 run_test 56aa "lfs find --size under striped dir"
8352
8353 test_56ab() { # LU-10705
8354         test_mkdir $DIR/$tdir
8355         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8356         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8357         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8358         # Flush writes to ensure valid blocks.  Need to be more thorough for
8359         # ZFS, since blocks are not allocated/returned to client immediately.
8360         sync_all_data
8361         wait_zfs_commit ost1 2
8362         cancel_lru_locks osc
8363         ls -ls $DIR/$tdir
8364
8365         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8366
8367         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8368
8369         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8370         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8371
8372         rm -f $DIR/$tdir/$tfile.[123]
8373 }
8374 run_test 56ab "lfs find --blocks"
8375
8376 # LU-11188
8377 test_56aca() {
8378         local dir="$DIR/$tdir"
8379         local perms=(001 002 003 004 005 006 007
8380                      010 020 030 040 050 060 070
8381                      100 200 300 400 500 600 700
8382                      111 222 333 444 555 666 777)
8383         local perm_minus=(8 8 4 8 4 4 2
8384                           8 8 4 8 4 4 2
8385                           8 8 4 8 4 4 2
8386                           4 4 2 4 2 2 1)
8387         local perm_slash=(8  8 12  8 12 12 14
8388                           8  8 12  8 12 12 14
8389                           8  8 12  8 12 12 14
8390                          16 16 24 16 24 24 28)
8391
8392         test_mkdir "$dir"
8393         for perm in ${perms[*]}; do
8394                 touch "$dir/$tfile.$perm"
8395                 chmod $perm "$dir/$tfile.$perm"
8396         done
8397
8398         for ((i = 0; i < ${#perms[*]}; i++)); do
8399                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8400                 (( $num == 1 )) ||
8401                         error "lfs find -perm ${perms[i]}:"\
8402                               "$num != 1"
8403
8404                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8405                 (( $num == ${perm_minus[i]} )) ||
8406                         error "lfs find -perm -${perms[i]}:"\
8407                               "$num != ${perm_minus[i]}"
8408
8409                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8410                 (( $num == ${perm_slash[i]} )) ||
8411                         error "lfs find -perm /${perms[i]}:"\
8412                               "$num != ${perm_slash[i]}"
8413         done
8414 }
8415 run_test 56aca "check lfs find -perm with octal representation"
8416
8417 test_56acb() {
8418         local dir=$DIR/$tdir
8419         # p is the permission of write and execute for user, group and other
8420         # without the umask. It is used to test +wx.
8421         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8422         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8423         local symbolic=(+t  a+t u+t g+t o+t
8424                         g+s u+s o+s +s o+sr
8425                         o=r,ug+o,u+w
8426                         u+ g+ o+ a+ ugo+
8427                         u- g- o- a- ugo-
8428                         u= g= o= a= ugo=
8429                         o=r,ug+o,u+w u=r,a+u,u+w
8430                         g=r,ugo=g,u+w u+x,+X +X
8431                         u+x,u+X u+X u+x,g+X o+r,+X
8432                         u+x,go+X +wx +rwx)
8433
8434         test_mkdir $dir
8435         for perm in ${perms[*]}; do
8436                 touch "$dir/$tfile.$perm"
8437                 chmod $perm "$dir/$tfile.$perm"
8438         done
8439
8440         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8441                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8442
8443                 (( $num == 1 )) ||
8444                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8445         done
8446 }
8447 run_test 56acb "check lfs find -perm with symbolic representation"
8448
8449 test_56acc() {
8450         local dir=$DIR/$tdir
8451         local tests="17777 787 789 abcd
8452                 ug=uu ug=a ug=gu uo=ou urw
8453                 u+xg+x a=r,u+x,"
8454
8455         test_mkdir $dir
8456         for err in $tests; do
8457                 if $LFS find $dir -perm $err 2>/dev/null; then
8458                         error "lfs find -perm $err: parsing should have failed"
8459                 fi
8460         done
8461 }
8462 run_test 56acc "check parsing error for lfs find -perm"
8463
8464 test_56ba() {
8465         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8466                 skip "Need MDS version at least 2.10.50"
8467
8468         # Create composite files with one component
8469         local dir=$DIR/$tdir
8470
8471         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8472         # Create composite files with three components
8473         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8474         # Create non-composite files
8475         createmany -o $dir/${tfile}- 10
8476
8477         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8478
8479         [[ $nfiles == 10 ]] ||
8480                 error "lfs find -E 1M found $nfiles != 10 files"
8481
8482         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8483         [[ $nfiles == 25 ]] ||
8484                 error "lfs find ! -E 1M found $nfiles != 25 files"
8485
8486         # All files have a component that starts at 0
8487         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8488         [[ $nfiles == 35 ]] ||
8489                 error "lfs find --component-start 0 - $nfiles != 35 files"
8490
8491         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8492         [[ $nfiles == 15 ]] ||
8493                 error "lfs find --component-start 2M - $nfiles != 15 files"
8494
8495         # All files created here have a componenet that does not starts at 2M
8496         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8497         [[ $nfiles == 35 ]] ||
8498                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8499
8500         # Find files with a specified number of components
8501         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8502         [[ $nfiles == 15 ]] ||
8503                 error "lfs find --component-count 3 - $nfiles != 15 files"
8504
8505         # Remember non-composite files have a component count of zero
8506         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8507         [[ $nfiles == 10 ]] ||
8508                 error "lfs find --component-count 0 - $nfiles != 10 files"
8509
8510         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8511         [[ $nfiles == 20 ]] ||
8512                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8513
8514         # All files have a flag called "init"
8515         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8516         [[ $nfiles == 35 ]] ||
8517                 error "lfs find --component-flags init - $nfiles != 35 files"
8518
8519         # Multi-component files will have a component not initialized
8520         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8521         [[ $nfiles == 15 ]] ||
8522                 error "lfs find !--component-flags init - $nfiles != 15 files"
8523
8524         rm -rf $dir
8525
8526 }
8527 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8528
8529 test_56ca() {
8530         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8531                 skip "Need MDS version at least 2.10.57"
8532
8533         local td=$DIR/$tdir
8534         local tf=$td/$tfile
8535         local dir
8536         local nfiles
8537         local cmd
8538         local i
8539         local j
8540
8541         # create mirrored directories and mirrored files
8542         mkdir $td || error "mkdir $td failed"
8543         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8544         createmany -o $tf- 10 || error "create $tf- failed"
8545
8546         for i in $(seq 2); do
8547                 dir=$td/dir$i
8548                 mkdir $dir || error "mkdir $dir failed"
8549                 $LFS mirror create -N$((3 + i)) $dir ||
8550                         error "create mirrored dir $dir failed"
8551                 createmany -o $dir/$tfile- 10 ||
8552                         error "create $dir/$tfile- failed"
8553         done
8554
8555         # change the states of some mirrored files
8556         echo foo > $tf-6
8557         for i in $(seq 2); do
8558                 dir=$td/dir$i
8559                 for j in $(seq 4 9); do
8560                         echo foo > $dir/$tfile-$j
8561                 done
8562         done
8563
8564         # find mirrored files with specific mirror count
8565         cmd="$LFS find --mirror-count 3 --type f $td"
8566         nfiles=$($cmd | wc -l)
8567         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8568
8569         cmd="$LFS find ! --mirror-count 3 --type f $td"
8570         nfiles=$($cmd | wc -l)
8571         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8572
8573         cmd="$LFS find --mirror-count +2 --type f $td"
8574         nfiles=$($cmd | wc -l)
8575         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8576
8577         cmd="$LFS find --mirror-count -6 --type f $td"
8578         nfiles=$($cmd | wc -l)
8579         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8580
8581         # find mirrored files with specific file state
8582         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8583         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8584
8585         cmd="$LFS find --mirror-state=ro --type f $td"
8586         nfiles=$($cmd | wc -l)
8587         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8588
8589         cmd="$LFS find ! --mirror-state=ro --type f $td"
8590         nfiles=$($cmd | wc -l)
8591         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8592
8593         cmd="$LFS find --mirror-state=wp --type f $td"
8594         nfiles=$($cmd | wc -l)
8595         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8596
8597         cmd="$LFS find ! --mirror-state=sp --type f $td"
8598         nfiles=$($cmd | wc -l)
8599         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8600 }
8601 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8602
8603 test_56da() { # LU-14179
8604         local path=$DIR/$tdir
8605
8606         test_mkdir $path
8607         cd $path
8608
8609         local longdir=$(str_repeat 'a' 255)
8610
8611         for i in {1..15}; do
8612                 path=$path/$longdir
8613                 test_mkdir $longdir
8614                 cd $longdir
8615         done
8616
8617         local len=${#path}
8618         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8619
8620         test_mkdir $lastdir
8621         cd $lastdir
8622         # PATH_MAX-1
8623         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8624
8625         # NAME_MAX
8626         touch $(str_repeat 'f' 255)
8627
8628         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8629                 error "lfs find reported an error"
8630
8631         rm -rf $DIR/$tdir
8632 }
8633 run_test 56da "test lfs find with long paths"
8634
8635 test_56ea() { #LU-10378
8636         local path=$DIR/$tdir
8637         local pool=$TESTNAME
8638
8639         # Create ost pool
8640         pool_add $pool || error "pool_add $pool failed"
8641         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8642                 error "adding targets to $pool failed"
8643
8644         # Set default pool on directory before creating file
8645         mkdir $path || error "mkdir $path failed"
8646         $LFS setstripe -p $pool $path ||
8647                 error "set OST pool on $pool failed"
8648         touch $path/$tfile || error "touch $path/$tfile failed"
8649
8650         # Compare basic file attributes from -printf and stat
8651         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8652         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8653
8654         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8655                 error "Attrs from lfs find and stat don't match"
8656
8657         # Compare Lustre attributes from lfs find and lfs getstripe
8658         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8659         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8660         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8661         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8662         local fpool=$($LFS getstripe --pool $path/$tfile)
8663         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8664
8665         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8666                 error "Attrs from lfs find and lfs getstripe don't match"
8667
8668         # Verify behavior for unknown escape/format sequences
8669         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8670
8671         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8672                 error "Escape/format codes don't match"
8673 }
8674 run_test 56ea "test lfs find -printf option"
8675
8676 test_56eb() {
8677         local dir=$DIR/$tdir
8678         local subdir_1=$dir/subdir_1
8679
8680         test_mkdir -p $subdir_1
8681         ln -s subdir_1 $dir/link_1
8682
8683         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8684                 error "symlink is not followed"
8685
8686         $LFS getstripe --no-follow $dir |
8687                 grep "^$dir/link_1 has no stripe info$" ||
8688                 error "symlink should not have stripe info"
8689
8690         touch $dir/testfile
8691         ln -s testfile $dir/file_link_2
8692
8693         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8694                 error "symlink is not followed"
8695
8696         $LFS getstripe --no-follow $dir |
8697                 grep "^$dir/file_link_2 has no stripe info$" ||
8698                 error "symlink should not have stripe info"
8699 }
8700 run_test 56eb "check lfs getstripe on symlink"
8701
8702 test_57a() {
8703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8704         # note test will not do anything if MDS is not local
8705         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8706                 skip_env "ldiskfs only test"
8707         fi
8708         remote_mds_nodsh && skip "remote MDS with nodsh"
8709
8710         local MNTDEV="osd*.*MDT*.mntdev"
8711         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8712         [ -z "$DEV" ] && error "can't access $MNTDEV"
8713         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8714                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8715                         error "can't access $DEV"
8716                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8717                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8718                 rm $TMP/t57a.dump
8719         done
8720 }
8721 run_test 57a "verify MDS filesystem created with large inodes =="
8722
8723 test_57b() {
8724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8725         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8726                 skip_env "ldiskfs only test"
8727         fi
8728         remote_mds_nodsh && skip "remote MDS with nodsh"
8729
8730         local dir=$DIR/$tdir
8731         local filecount=100
8732         local file1=$dir/f1
8733         local fileN=$dir/f$filecount
8734
8735         rm -rf $dir || error "removing $dir"
8736         test_mkdir -c1 $dir
8737         local mdtidx=$($LFS getstripe -m $dir)
8738         local mdtname=MDT$(printf %04x $mdtidx)
8739         local facet=mds$((mdtidx + 1))
8740
8741         echo "mcreating $filecount files"
8742         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8743
8744         # verify that files do not have EAs yet
8745         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8746                 error "$file1 has an EA"
8747         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8748                 error "$fileN has an EA"
8749
8750         sync
8751         sleep 1
8752         df $dir  #make sure we get new statfs data
8753         local mdsfree=$(do_facet $facet \
8754                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8755         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8756         local file
8757
8758         echo "opening files to create objects/EAs"
8759         for file in $(seq -f $dir/f%g 1 $filecount); do
8760                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8761                         error "opening $file"
8762         done
8763
8764         # verify that files have EAs now
8765         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8766         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8767
8768         sleep 1  #make sure we get new statfs data
8769         df $dir
8770         local mdsfree2=$(do_facet $facet \
8771                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8772         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8773
8774         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8775                 if [ "$mdsfree" != "$mdsfree2" ]; then
8776                         error "MDC before $mdcfree != after $mdcfree2"
8777                 else
8778                         echo "MDC before $mdcfree != after $mdcfree2"
8779                         echo "unable to confirm if MDS has large inodes"
8780                 fi
8781         fi
8782         rm -rf $dir
8783 }
8784 run_test 57b "default LOV EAs are stored inside large inodes ==="
8785
8786 test_58() {
8787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8788         [ -z "$(which wiretest 2>/dev/null)" ] &&
8789                         skip_env "could not find wiretest"
8790
8791         wiretest
8792 }
8793 run_test 58 "verify cross-platform wire constants =============="
8794
8795 test_59() {
8796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8797
8798         echo "touch 130 files"
8799         createmany -o $DIR/f59- 130
8800         echo "rm 130 files"
8801         unlinkmany $DIR/f59- 130
8802         sync
8803         # wait for commitment of removal
8804         wait_delete_completed
8805 }
8806 run_test 59 "verify cancellation of llog records async ========="
8807
8808 TEST60_HEAD="test_60 run $RANDOM"
8809 test_60a() {
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8811         remote_mgs_nodsh && skip "remote MGS with nodsh"
8812         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8813                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8814                         skip_env "missing subtest run-llog.sh"
8815
8816         log "$TEST60_HEAD - from kernel mode"
8817         do_facet mgs "$LCTL dk > /dev/null"
8818         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8819         do_facet mgs $LCTL dk > $TMP/$tfile
8820
8821         # LU-6388: test llog_reader
8822         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8823         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8824         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8825                         skip_env "missing llog_reader"
8826         local fstype=$(facet_fstype mgs)
8827         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8828                 skip_env "Only for ldiskfs or zfs type mgs"
8829
8830         local mntpt=$(facet_mntpt mgs)
8831         local mgsdev=$(mgsdevname 1)
8832         local fid_list
8833         local fid
8834         local rec_list
8835         local rec
8836         local rec_type
8837         local obj_file
8838         local path
8839         local seq
8840         local oid
8841         local pass=true
8842
8843         #get fid and record list
8844         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8845                 tail -n 4))
8846         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8847                 tail -n 4))
8848         #remount mgs as ldiskfs or zfs type
8849         stop mgs || error "stop mgs failed"
8850         mount_fstype mgs || error "remount mgs failed"
8851         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8852                 fid=${fid_list[i]}
8853                 rec=${rec_list[i]}
8854                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8855                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8856                 oid=$((16#$oid))
8857
8858                 case $fstype in
8859                         ldiskfs )
8860                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8861                         zfs )
8862                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8863                 esac
8864                 echo "obj_file is $obj_file"
8865                 do_facet mgs $llog_reader $obj_file
8866
8867                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8868                         awk '{ print $3 }' | sed -e "s/^type=//g")
8869                 if [ $rec_type != $rec ]; then
8870                         echo "FAILED test_60a wrong record type $rec_type," \
8871                               "should be $rec"
8872                         pass=false
8873                         break
8874                 fi
8875
8876                 #check obj path if record type is LLOG_LOGID_MAGIC
8877                 if [ "$rec" == "1064553b" ]; then
8878                         path=$(do_facet mgs $llog_reader $obj_file |
8879                                 grep "path=" | awk '{ print $NF }' |
8880                                 sed -e "s/^path=//g")
8881                         if [ $obj_file != $mntpt/$path ]; then
8882                                 echo "FAILED test_60a wrong obj path" \
8883                                       "$montpt/$path, should be $obj_file"
8884                                 pass=false
8885                                 break
8886                         fi
8887                 fi
8888         done
8889         rm -f $TMP/$tfile
8890         #restart mgs before "error", otherwise it will block the next test
8891         stop mgs || error "stop mgs failed"
8892         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8893         $pass || error "test failed, see FAILED test_60a messages for specifics"
8894 }
8895 run_test 60a "llog_test run from kernel module and test llog_reader"
8896
8897 test_60b() { # bug 6411
8898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8899
8900         dmesg > $DIR/$tfile
8901         LLOG_COUNT=$(do_facet mgs dmesg |
8902                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8903                           /llog_[a-z]*.c:[0-9]/ {
8904                                 if (marker)
8905                                         from_marker++
8906                                 from_begin++
8907                           }
8908                           END {
8909                                 if (marker)
8910                                         print from_marker
8911                                 else
8912                                         print from_begin
8913                           }")
8914
8915         [[ $LLOG_COUNT -gt 120 ]] &&
8916                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8917 }
8918 run_test 60b "limit repeated messages from CERROR/CWARN"
8919
8920 test_60c() {
8921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8922
8923         echo "create 5000 files"
8924         createmany -o $DIR/f60c- 5000
8925 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8926         lctl set_param fail_loc=0x80000137
8927         unlinkmany $DIR/f60c- 5000
8928         lctl set_param fail_loc=0
8929 }
8930 run_test 60c "unlink file when mds full"
8931
8932 test_60d() {
8933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8934
8935         SAVEPRINTK=$(lctl get_param -n printk)
8936         # verify "lctl mark" is even working"
8937         MESSAGE="test message ID $RANDOM $$"
8938         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8939         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8940
8941         lctl set_param printk=0 || error "set lnet.printk failed"
8942         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8943         MESSAGE="new test message ID $RANDOM $$"
8944         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8945         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8946         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8947
8948         lctl set_param -n printk="$SAVEPRINTK"
8949 }
8950 run_test 60d "test printk console message masking"
8951
8952 test_60e() {
8953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8954         remote_mds_nodsh && skip "remote MDS with nodsh"
8955
8956         touch $DIR/$tfile
8957 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8958         do_facet mds1 lctl set_param fail_loc=0x15b
8959         rm $DIR/$tfile
8960 }
8961 run_test 60e "no space while new llog is being created"
8962
8963 test_60f() {
8964         local old_path=$($LCTL get_param -n debug_path)
8965
8966         stack_trap "$LCTL set_param debug_path=$old_path"
8967         stack_trap "rm -f $TMP/$tfile*"
8968         rm -f $TMP/$tfile* 2> /dev/null
8969         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8970         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8971         test_mkdir $DIR/$tdir
8972         # retry in case the open is cached and not released
8973         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8974                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8975                 sleep 0.1
8976         done
8977         ls $TMP/$tfile*
8978         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8979 }
8980 run_test 60f "change debug_path works"
8981
8982 test_60g() {
8983         local pid
8984         local i
8985
8986         test_mkdir -c $MDSCOUNT $DIR/$tdir
8987
8988         (
8989                 local index=0
8990                 while true; do
8991                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8992                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8993                                 2>/dev/null
8994                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8995                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8996                         index=$((index + 1))
8997                 done
8998         ) &
8999
9000         pid=$!
9001
9002         for i in {0..100}; do
9003                 # define OBD_FAIL_OSD_TXN_START    0x19a
9004                 local index=$((i % MDSCOUNT + 1))
9005
9006                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9007                         > /dev/null
9008                 sleep 0.01
9009         done
9010
9011         kill -9 $pid
9012
9013         for i in $(seq $MDSCOUNT); do
9014                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9015         done
9016
9017         mkdir $DIR/$tdir/new || error "mkdir failed"
9018         rmdir $DIR/$tdir/new || error "rmdir failed"
9019
9020         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9021                 -t namespace
9022         for i in $(seq $MDSCOUNT); do
9023                 wait_update_facet mds$i "$LCTL get_param -n \
9024                         mdd.$(facet_svc mds$i).lfsck_namespace |
9025                         awk '/^status/ { print \\\$2 }'" "completed"
9026         done
9027
9028         ls -R $DIR/$tdir
9029         rm -rf $DIR/$tdir || error "rmdir failed"
9030 }
9031 run_test 60g "transaction abort won't cause MDT hung"
9032
9033 test_60h() {
9034         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9035                 skip "Need MDS version at least 2.12.52"
9036         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9037
9038         local f
9039
9040         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9041         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9042         for fail_loc in 0x80000188 0x80000189; do
9043                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9044                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9045                         error "mkdir $dir-$fail_loc failed"
9046                 for i in {0..10}; do
9047                         # create may fail on missing stripe
9048                         echo $i > $DIR/$tdir-$fail_loc/$i
9049                 done
9050                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9051                         error "getdirstripe $tdir-$fail_loc failed"
9052                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9053                         error "migrate $tdir-$fail_loc failed"
9054                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9055                         error "getdirstripe $tdir-$fail_loc failed"
9056                 pushd $DIR/$tdir-$fail_loc
9057                 for f in *; do
9058                         echo $f | cmp $f - || error "$f data mismatch"
9059                 done
9060                 popd
9061                 rm -rf $DIR/$tdir-$fail_loc
9062         done
9063 }
9064 run_test 60h "striped directory with missing stripes can be accessed"
9065
9066 function t60i_load() {
9067         mkdir $DIR/$tdir
9068         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9069         $LCTL set_param fail_loc=0x131c fail_val=1
9070         for ((i=0; i<5000; i++)); do
9071                 touch $DIR/$tdir/f$i
9072         done
9073 }
9074
9075 test_60i() {
9076         changelog_register || error "changelog_register failed"
9077         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9078         changelog_users $SINGLEMDS | grep -q $cl_user ||
9079                 error "User $cl_user not found in changelog_users"
9080         changelog_chmask "ALL"
9081         t60i_load &
9082         local PID=$!
9083         for((i=0; i<100; i++)); do
9084                 changelog_dump >/dev/null ||
9085                         error "can't read changelog"
9086         done
9087         kill $PID
9088         wait $PID
9089         changelog_deregister || error "changelog_deregister failed"
9090         $LCTL set_param fail_loc=0
9091 }
9092 run_test 60i "llog: new record vs reader race"
9093
9094 test_60j() {
9095         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9096                 skip "need MDS version at least 2.15.50"
9097         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9098         remote_mds_nodsh && skip "remote MDS with nodsh"
9099         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9100
9101         changelog_users $SINGLEMDS | grep "^cl" &&
9102                 skip "active changelog user"
9103
9104         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9105
9106         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9107                 skip_env "missing llog_reader"
9108
9109         mkdir_on_mdt0 $DIR/$tdir
9110
9111         local f=$DIR/$tdir/$tfile
9112         local mdt_dev
9113         local tmpfile
9114         local plain
9115
9116         changelog_register || error "cannot register changelog user"
9117
9118         # set changelog_mask to ALL
9119         changelog_chmask "ALL"
9120         changelog_clear
9121
9122         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9123         unlinkmany ${f}- 100 || error "unlinkmany failed"
9124
9125         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9126         mdt_dev=$(facet_device $SINGLEMDS)
9127
9128         do_facet $SINGLEMDS sync
9129         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9130                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9131                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9132
9133         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9134
9135         # if $tmpfile is not on EXT3 filesystem for some reason
9136         [[ ${plain:0:1} == 'O' ]] ||
9137                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9138
9139         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9140                 $mdt_dev; stat -c %s $tmpfile")
9141         echo "Truncate llog from $size to $((size - size % 8192))"
9142         size=$((size - size % 8192))
9143         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9144         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9145                 grep -c 'in bitmap only')
9146         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9147
9148         size=$((size - 9000))
9149         echo "Corrupt llog in the middle at $size"
9150         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9151                 count=333 conv=notrunc
9152         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9153                 grep -c 'next chunk')
9154         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9155 }
9156 run_test 60j "llog_reader reports corruptions"
9157
9158 test_61a() {
9159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9160
9161         f="$DIR/f61"
9162         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9163         cancel_lru_locks osc
9164         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9165         sync
9166 }
9167 run_test 61a "mmap() writes don't make sync hang ================"
9168
9169 test_61b() {
9170         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9171 }
9172 run_test 61b "mmap() of unstriped file is successful"
9173
9174 # bug 2330 - insufficient obd_match error checking causes LBUG
9175 test_62() {
9176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9177
9178         f="$DIR/f62"
9179         echo foo > $f
9180         cancel_lru_locks osc
9181         lctl set_param fail_loc=0x405
9182         cat $f && error "cat succeeded, expect -EIO"
9183         lctl set_param fail_loc=0
9184 }
9185 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9186 # match every page all of the time.
9187 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9188
9189 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9190 # Though this test is irrelevant anymore, it helped to reveal some
9191 # other grant bugs (LU-4482), let's keep it.
9192 test_63a() {   # was test_63
9193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9194
9195         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9196
9197         for i in `seq 10` ; do
9198                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9199                 sleep 5
9200                 kill $!
9201                 sleep 1
9202         done
9203
9204         rm -f $DIR/f63 || true
9205 }
9206 run_test 63a "Verify oig_wait interruption does not crash ======="
9207
9208 # bug 2248 - async write errors didn't return to application on sync
9209 # bug 3677 - async write errors left page locked
9210 test_63b() {
9211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9212
9213         debugsave
9214         lctl set_param debug=-1
9215
9216         # ensure we have a grant to do async writes
9217         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9218         rm $DIR/$tfile
9219
9220         sync    # sync lest earlier test intercept the fail_loc
9221
9222         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9223         lctl set_param fail_loc=0x80000406
9224         $MULTIOP $DIR/$tfile Owy && \
9225                 error "sync didn't return ENOMEM"
9226         sync; sleep 2; sync     # do a real sync this time to flush page
9227         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9228                 error "locked page left in cache after async error" || true
9229         debugrestore
9230 }
9231 run_test 63b "async write errors should be returned to fsync ==="
9232
9233 test_64a () {
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235
9236         lfs df $DIR
9237         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9238 }
9239 run_test 64a "verify filter grant calculations (in kernel) ====="
9240
9241 test_64b () {
9242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9243
9244         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9245 }
9246 run_test 64b "check out-of-space detection on client"
9247
9248 test_64c() {
9249         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9250 }
9251 run_test 64c "verify grant shrink"
9252
9253 import_param() {
9254         local tgt=$1
9255         local param=$2
9256
9257         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9258 }
9259
9260 # this does exactly what osc_request.c:osc_announce_cached() does in
9261 # order to calculate max amount of grants to ask from server
9262 want_grant() {
9263         local tgt=$1
9264
9265         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9266         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9267
9268         ((rpc_in_flight++));
9269         nrpages=$((nrpages * rpc_in_flight))
9270
9271         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9272
9273         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9274
9275         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9276         local undirty=$((nrpages * PAGE_SIZE))
9277
9278         local max_extent_pages
9279         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9280         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9281         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9282         local grant_extent_tax
9283         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9284
9285         undirty=$((undirty + nrextents * grant_extent_tax))
9286
9287         echo $undirty
9288 }
9289
9290 # this is size of unit for grant allocation. It should be equal to
9291 # what tgt_grant.c:tgt_grant_chunk() calculates
9292 grant_chunk() {
9293         local tgt=$1
9294         local max_brw_size
9295         local grant_extent_tax
9296
9297         max_brw_size=$(import_param $tgt max_brw_size)
9298
9299         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9300
9301         echo $(((max_brw_size + grant_extent_tax) * 2))
9302 }
9303
9304 test_64d() {
9305         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9306                 skip "OST < 2.10.55 doesn't limit grants enough"
9307
9308         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9309
9310         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9311                 skip "no grant_param connect flag"
9312
9313         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9314
9315         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9316         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9317
9318
9319         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9320         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9321
9322         $LFS setstripe $DIR/$tfile -i 0 -c 1
9323         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9324         ddpid=$!
9325
9326         while kill -0 $ddpid; do
9327                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9328
9329                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9330                         kill $ddpid
9331                         error "cur_grant $cur_grant > $max_cur_granted"
9332                 fi
9333
9334                 sleep 1
9335         done
9336 }
9337 run_test 64d "check grant limit exceed"
9338
9339 check_grants() {
9340         local tgt=$1
9341         local expected=$2
9342         local msg=$3
9343         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9344
9345         ((cur_grants == expected)) ||
9346                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9347 }
9348
9349 round_up_p2() {
9350         echo $((($1 + $2 - 1) & ~($2 - 1)))
9351 }
9352
9353 test_64e() {
9354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9355         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9356                 skip "Need OSS version at least 2.11.56"
9357
9358         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9359         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9360         $LCTL set_param debug=+cache
9361
9362         # Remount client to reset grant
9363         remount_client $MOUNT || error "failed to remount client"
9364         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9365
9366         local init_grants=$(import_param $osc_tgt initial_grant)
9367
9368         check_grants $osc_tgt $init_grants "init grants"
9369
9370         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9371         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9372         local gbs=$(import_param $osc_tgt grant_block_size)
9373
9374         # write random number of bytes from max_brw_size / 4 to max_brw_size
9375         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9376         # align for direct io
9377         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9378         # round to grant consumption unit
9379         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9380
9381         local grants=$((wb_round_up + extent_tax))
9382
9383         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9384
9385         # define OBD_FAIL_TGT_NO_GRANT 0x725
9386         # make the server not grant more back
9387         do_facet ost1 $LCTL set_param fail_loc=0x725
9388         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9389
9390         do_facet ost1 $LCTL set_param fail_loc=0
9391
9392         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9393
9394         rm -f $DIR/$tfile || error "rm failed"
9395
9396         # Remount client to reset grant
9397         remount_client $MOUNT || error "failed to remount client"
9398         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9399
9400         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9401
9402         # define OBD_FAIL_TGT_NO_GRANT 0x725
9403         # make the server not grant more back
9404         do_facet ost1 $LCTL set_param fail_loc=0x725
9405         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9406         do_facet ost1 $LCTL set_param fail_loc=0
9407
9408         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9409 }
9410 run_test 64e "check grant consumption (no grant allocation)"
9411
9412 test_64f() {
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9414
9415         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9416         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9417         $LCTL set_param debug=+cache
9418
9419         # Remount client to reset grant
9420         remount_client $MOUNT || error "failed to remount client"
9421         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9422
9423         local init_grants=$(import_param $osc_tgt initial_grant)
9424         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9425         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9426         local gbs=$(import_param $osc_tgt grant_block_size)
9427         local chunk=$(grant_chunk $osc_tgt)
9428
9429         # write random number of bytes from max_brw_size / 4 to max_brw_size
9430         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9431         # align for direct io
9432         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9433         # round to grant consumption unit
9434         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9435
9436         local grants=$((wb_round_up + extent_tax))
9437
9438         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9439         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9440                 error "error writing to $DIR/$tfile"
9441
9442         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9443                 "direct io with grant allocation"
9444
9445         rm -f $DIR/$tfile || error "rm failed"
9446
9447         # Remount client to reset grant
9448         remount_client $MOUNT || error "failed to remount client"
9449         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9450
9451         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9452
9453         local cmd="oO_WRONLY:w${write_bytes}_yc"
9454
9455         $MULTIOP $DIR/$tfile $cmd &
9456         MULTIPID=$!
9457         sleep 1
9458
9459         check_grants $osc_tgt $((init_grants - grants)) \
9460                 "buffered io, not write rpc"
9461
9462         kill -USR1 $MULTIPID
9463         wait
9464
9465         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9466                 "buffered io, one RPC"
9467 }
9468 run_test 64f "check grant consumption (with grant allocation)"
9469
9470 test_64g() {
9471         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9472                 skip "Need MDS version at least 2.14.56"
9473
9474         local mdts=$(comma_list $(mdts_nodes))
9475
9476         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9477                         tr '\n' ' ')
9478         stack_trap "$LCTL set_param $old"
9479
9480         # generate dirty pages and increase dirty granted on MDT
9481         stack_trap "rm -f $DIR/$tfile-*"
9482         for (( i = 0; i < 10; i++)); do
9483                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9484                         error "can't set stripe"
9485                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9486                         error "can't dd"
9487                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9488                         $LFS getstripe $DIR/$tfile-$i
9489                         error "not DoM file"
9490                 }
9491         done
9492
9493         # flush dirty pages
9494         sync
9495
9496         # wait until grant shrink reset grant dirty on MDTs
9497         for ((i = 0; i < 120; i++)); do
9498                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9499                         awk '{sum=sum+$1} END {print sum}')
9500                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9501                 echo "$grant_dirty grants, $vm_dirty pages"
9502                 (( grant_dirty + vm_dirty == 0 )) && break
9503                 (( i == 3 )) && sync &&
9504                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9505                 sleep 1
9506         done
9507
9508         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9509                 awk '{sum=sum+$1} END {print sum}')
9510         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9511 }
9512 run_test 64g "grant shrink on MDT"
9513
9514 test_64h() {
9515         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9516                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9517
9518         local instance=$($LFS getname -i $DIR)
9519         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9520         local num_exps=$(do_facet ost1 \
9521             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9522         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9523         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9524         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9525
9526         # 10MiB is for file to be written, max_brw_size * 16 *
9527         # num_exps is space reserve so that tgt_grant_shrink() decided
9528         # to not shrink
9529         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9530         (( avail * 1024 < expect )) &&
9531                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9532
9533         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9534         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9535         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9536         $LCTL set_param osc.*OST0000*.grant_shrink=1
9537         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9538
9539         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9541
9542         # drop cache so that coming read would do rpc
9543         cancel_lru_locks osc
9544
9545         # shrink interval is set to 10, pause for 7 seconds so that
9546         # grant thread did not wake up yet but coming read entered
9547         # shrink mode for rpc (osc_should_shrink_grant())
9548         sleep 7
9549
9550         declare -a cur_grant_bytes
9551         declare -a tot_granted
9552         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9553         tot_granted[0]=$(do_facet ost1 \
9554             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9555
9556         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9557
9558         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9559         tot_granted[1]=$(do_facet ost1 \
9560             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9561
9562         # grant change should be equal on both sides
9563         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9564                 tot_granted[0] - tot_granted[1])) ||
9565                 error "grant change mismatch, "                                \
9566                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9567                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9568 }
9569 run_test 64h "grant shrink on read"
9570
9571 test_64i() {
9572         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9573                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9574
9575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9576         remote_ost_nodsh && skip "remote OSTs with nodsh"
9577
9578         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9579
9580         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9581
9582         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9583         local instance=$($LFS getname -i $DIR)
9584
9585         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9586         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9587
9588         # shrink grants and simulate rpc loss
9589         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9590         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9591         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9592
9593         fail ost1
9594
9595         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9596
9597         local testid=$(echo $TESTNAME | tr '_' ' ')
9598
9599         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9600                 grep "GRANT, real grant" &&
9601                 error "client has more grants then it owns" || true
9602 }
9603 run_test 64i "shrink on reconnect"
9604
9605 # bug 1414 - set/get directories' stripe info
9606 test_65a() {
9607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9608
9609         test_mkdir $DIR/$tdir
9610         touch $DIR/$tdir/f1
9611         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9612 }
9613 run_test 65a "directory with no stripe info"
9614
9615 test_65b() {
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617
9618         test_mkdir $DIR/$tdir
9619         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9620
9621         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9622                                                 error "setstripe"
9623         touch $DIR/$tdir/f2
9624         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9625 }
9626 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9627
9628 test_65c() {
9629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9630         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9631
9632         test_mkdir $DIR/$tdir
9633         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9634
9635         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9636                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9637         touch $DIR/$tdir/f3
9638         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9639 }
9640 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9641
9642 test_65d() {
9643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9644
9645         test_mkdir $DIR/$tdir
9646         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9647         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9648
9649         if [[ $STRIPECOUNT -le 0 ]]; then
9650                 sc=1
9651         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9652                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9653                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9654         else
9655                 sc=$(($STRIPECOUNT - 1))
9656         fi
9657         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9658         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9659         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9660                 error "lverify failed"
9661 }
9662 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9663
9664 test_65e() {
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666
9667         test_mkdir $DIR/$tdir
9668
9669         $LFS setstripe $DIR/$tdir || error "setstripe"
9670         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9671                                         error "no stripe info failed"
9672         touch $DIR/$tdir/f6
9673         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9674 }
9675 run_test 65e "directory setstripe defaults"
9676
9677 test_65f() {
9678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9679
9680         test_mkdir $DIR/${tdir}f
9681         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9682                 error "setstripe succeeded" || true
9683 }
9684 run_test 65f "dir setstripe permission (should return error) ==="
9685
9686 test_65g() {
9687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9688
9689         test_mkdir $DIR/$tdir
9690         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9691
9692         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9693                 error "setstripe -S failed"
9694         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9695         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9696                 error "delete default stripe failed"
9697 }
9698 run_test 65g "directory setstripe -d"
9699
9700 test_65h() {
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702
9703         test_mkdir $DIR/$tdir
9704         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9705
9706         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9707                 error "setstripe -S failed"
9708         test_mkdir $DIR/$tdir/dd1
9709         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9710                 error "stripe info inherit failed"
9711 }
9712 run_test 65h "directory stripe info inherit ===================="
9713
9714 test_65i() {
9715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9716
9717         save_layout_restore_at_exit $MOUNT
9718
9719         # bug6367: set non-default striping on root directory
9720         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9721
9722         # bug12836: getstripe on -1 default directory striping
9723         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9724
9725         # bug12836: getstripe -v on -1 default directory striping
9726         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9727
9728         # bug12836: new find on -1 default directory striping
9729         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9730 }
9731 run_test 65i "various tests to set root directory striping"
9732
9733 test_65j() { # bug6367
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735
9736         sync; sleep 1
9737
9738         # if we aren't already remounting for each test, do so for this test
9739         if [ "$I_MOUNTED" = "yes" ]; then
9740                 cleanup || error "failed to unmount"
9741                 setup
9742         fi
9743
9744         save_layout_restore_at_exit $MOUNT
9745
9746         $LFS setstripe -d $MOUNT || error "setstripe failed"
9747 }
9748 run_test 65j "set default striping on root directory (bug 6367)="
9749
9750 cleanup_65k() {
9751         rm -rf $DIR/$tdir
9752         wait_delete_completed
9753         do_facet $SINGLEMDS "lctl set_param -n \
9754                 osp.$ost*MDT0000.max_create_count=$max_count"
9755         do_facet $SINGLEMDS "lctl set_param -n \
9756                 osp.$ost*MDT0000.create_count=$count"
9757         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9758         echo $INACTIVE_OSC "is Activate"
9759
9760         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9761 }
9762
9763 test_65k() { # bug11679
9764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9766         remote_mds_nodsh && skip "remote MDS with nodsh"
9767
9768         local disable_precreate=true
9769         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9770                 disable_precreate=false
9771
9772         echo "Check OST status: "
9773         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9774                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9775
9776         for OSC in $MDS_OSCS; do
9777                 echo $OSC "is active"
9778                 do_facet $SINGLEMDS lctl --device %$OSC activate
9779         done
9780
9781         for INACTIVE_OSC in $MDS_OSCS; do
9782                 local ost=$(osc_to_ost $INACTIVE_OSC)
9783                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9784                                lov.*md*.target_obd |
9785                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9786
9787                 mkdir -p $DIR/$tdir
9788                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9789                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9790
9791                 echo "Deactivate: " $INACTIVE_OSC
9792                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9793
9794                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9795                               osp.$ost*MDT0000.create_count")
9796                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9797                                   osp.$ost*MDT0000.max_create_count")
9798                 $disable_precreate &&
9799                         do_facet $SINGLEMDS "lctl set_param -n \
9800                                 osp.$ost*MDT0000.max_create_count=0"
9801
9802                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9803                         [ -f $DIR/$tdir/$idx ] && continue
9804                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9805                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9806                                 { cleanup_65k;
9807                                   error "setstripe $idx should succeed"; }
9808                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9809                 done
9810                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9811                 rmdir $DIR/$tdir
9812
9813                 do_facet $SINGLEMDS "lctl set_param -n \
9814                         osp.$ost*MDT0000.max_create_count=$max_count"
9815                 do_facet $SINGLEMDS "lctl set_param -n \
9816                         osp.$ost*MDT0000.create_count=$count"
9817                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9818                 echo $INACTIVE_OSC "is Activate"
9819
9820                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9821         done
9822 }
9823 run_test 65k "validate manual striping works properly with deactivated OSCs"
9824
9825 test_65l() { # bug 12836
9826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9827
9828         test_mkdir -p $DIR/$tdir/test_dir
9829         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9830         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9831 }
9832 run_test 65l "lfs find on -1 stripe dir ========================"
9833
9834 test_65m() {
9835         local layout=$(save_layout $MOUNT)
9836         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9837                 restore_layout $MOUNT $layout
9838                 error "setstripe should fail by non-root users"
9839         }
9840         true
9841 }
9842 run_test 65m "normal user can't set filesystem default stripe"
9843
9844 test_65n() {
9845         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9846         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9847                 skip "Need MDS version at least 2.12.50"
9848         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9849
9850         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9851         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9852         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9853
9854         save_layout_restore_at_exit $MOUNT
9855
9856         # new subdirectory under root directory should not inherit
9857         # the default layout from root
9858         local dir1=$MOUNT/$tdir-1
9859         mkdir $dir1 || error "mkdir $dir1 failed"
9860         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9861                 error "$dir1 shouldn't have LOV EA"
9862
9863         # delete the default layout on root directory
9864         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9865
9866         local dir2=$MOUNT/$tdir-2
9867         mkdir $dir2 || error "mkdir $dir2 failed"
9868         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9869                 error "$dir2 shouldn't have LOV EA"
9870
9871         # set a new striping pattern on root directory
9872         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9873         local new_def_stripe_size=$((def_stripe_size * 2))
9874         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9875                 error "set stripe size on $MOUNT failed"
9876
9877         # new file created in $dir2 should inherit the new stripe size from
9878         # the filesystem default
9879         local file2=$dir2/$tfile-2
9880         touch $file2 || error "touch $file2 failed"
9881
9882         local file2_stripe_size=$($LFS getstripe -S $file2)
9883         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9884         {
9885                 echo "file2_stripe_size: '$file2_stripe_size'"
9886                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9887                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9888         }
9889
9890         local dir3=$MOUNT/$tdir-3
9891         mkdir $dir3 || error "mkdir $dir3 failed"
9892         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9893         # the root layout, which is the actual default layout that will be used
9894         # when new files are created in $dir3.
9895         local dir3_layout=$(get_layout_param $dir3)
9896         local root_dir_layout=$(get_layout_param $MOUNT)
9897         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9898         {
9899                 echo "dir3_layout: '$dir3_layout'"
9900                 echo "root_dir_layout: '$root_dir_layout'"
9901                 error "$dir3 should show the default layout from $MOUNT"
9902         }
9903
9904         # set OST pool on root directory
9905         local pool=$TESTNAME
9906         pool_add $pool || error "add $pool failed"
9907         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9908                 error "add targets to $pool failed"
9909
9910         $LFS setstripe -p $pool $MOUNT ||
9911                 error "set OST pool on $MOUNT failed"
9912
9913         # new file created in $dir3 should inherit the pool from
9914         # the filesystem default
9915         local file3=$dir3/$tfile-3
9916         touch $file3 || error "touch $file3 failed"
9917
9918         local file3_pool=$($LFS getstripe -p $file3)
9919         [[ "$file3_pool" = "$pool" ]] ||
9920                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9921
9922         local dir4=$MOUNT/$tdir-4
9923         mkdir $dir4 || error "mkdir $dir4 failed"
9924         local dir4_layout=$(get_layout_param $dir4)
9925         root_dir_layout=$(get_layout_param $MOUNT)
9926         echo "$LFS getstripe -d $dir4"
9927         $LFS getstripe -d $dir4
9928         echo "$LFS getstripe -d $MOUNT"
9929         $LFS getstripe -d $MOUNT
9930         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9931         {
9932                 echo "dir4_layout: '$dir4_layout'"
9933                 echo "root_dir_layout: '$root_dir_layout'"
9934                 error "$dir4 should show the default layout from $MOUNT"
9935         }
9936
9937         # new file created in $dir4 should inherit the pool from
9938         # the filesystem default
9939         local file4=$dir4/$tfile-4
9940         touch $file4 || error "touch $file4 failed"
9941
9942         local file4_pool=$($LFS getstripe -p $file4)
9943         [[ "$file4_pool" = "$pool" ]] ||
9944                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9945
9946         # new subdirectory under non-root directory should inherit
9947         # the default layout from its parent directory
9948         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9949                 error "set directory layout on $dir4 failed"
9950
9951         local dir5=$dir4/$tdir-5
9952         mkdir $dir5 || error "mkdir $dir5 failed"
9953
9954         dir4_layout=$(get_layout_param $dir4)
9955         local dir5_layout=$(get_layout_param $dir5)
9956         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9957         {
9958                 echo "dir4_layout: '$dir4_layout'"
9959                 echo "dir5_layout: '$dir5_layout'"
9960                 error "$dir5 should inherit the default layout from $dir4"
9961         }
9962
9963         # though subdir under ROOT doesn't inherit default layout, but
9964         # its sub dir/file should be created with default layout.
9965         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9966         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9967                 skip "Need MDS version at least 2.12.59"
9968
9969         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9970         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9971         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9972
9973         if [ $default_lmv_hash == "none" ]; then
9974                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9975         else
9976                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9977                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9978         fi
9979
9980         $LFS setdirstripe -D -c 2 $MOUNT ||
9981                 error "setdirstripe -D -c 2 failed"
9982         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9983         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9984         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9985
9986         # $dir4 layout includes pool
9987         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9988         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9989                 error "pool lost on setstripe"
9990         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9991         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9992                 error "pool lost on compound layout setstripe"
9993 }
9994 run_test 65n "don't inherit default layout from root for new subdirectories"
9995
9996 test_65o() {
9997         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9998                 skip "need MDS version at least 2.14.57"
9999
10000         # set OST pool on root directory
10001         local pool=$TESTNAME
10002
10003         pool_add $pool || error "add $pool failed"
10004         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10005                 error "add targets to $pool failed"
10006
10007         local dir1=$MOUNT/$tdir
10008
10009         mkdir $dir1 || error "mkdir $dir1 failed"
10010
10011         # set a new striping pattern on root directory
10012         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10013
10014         $LFS setstripe -p $pool $dir1 ||
10015                 error "set directory layout on $dir1 failed"
10016
10017         # $dir1 layout includes pool
10018         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10019         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10020                 error "pool lost on setstripe"
10021         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10022         $LFS getstripe $dir1
10023         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10024                 error "pool lost on compound layout setstripe"
10025
10026         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10027                 error "setdirstripe failed on sub-dir with inherited pool"
10028         $LFS getstripe $dir1/dir2
10029         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10030                 error "pool lost on compound layout setdirstripe"
10031
10032         $LFS setstripe -E -1 -c 1 $dir1
10033         $LFS getstripe -d $dir1
10034         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10035                 error "pool lost on setstripe"
10036 }
10037 run_test 65o "pool inheritance for mdt component"
10038
10039 test_65p () { # LU-16152
10040         local src_dir=$DIR/$tdir/src_dir
10041         local dst_dir=$DIR/$tdir/dst_dir
10042         local yaml_file=$DIR/$tdir/layout.yaml
10043         local border
10044
10045         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10046                 skip "Need at least version 2.15.51"
10047
10048         test_mkdir -p $src_dir
10049         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10050                 error "failed to setstripe"
10051         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10052                 error "failed to getstripe"
10053
10054         test_mkdir -p $dst_dir
10055         $LFS setstripe --yaml $yaml_file $dst_dir ||
10056                 error "failed to setstripe with yaml file"
10057         border=$($LFS getstripe -d $dst_dir |
10058                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10059                 error "failed to getstripe"
10060
10061         # 2048M is 0x80000000, or 2147483648
10062         (( $border == 2147483648 )) ||
10063                 error "failed to handle huge number in yaml layout"
10064 }
10065 run_test 65p "setstripe with yaml file and huge number"
10066
10067 # bug 2543 - update blocks count on client
10068 test_66() {
10069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10070
10071         local COUNT=${COUNT:-8}
10072         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10073         sync; sync_all_data; sync; sync_all_data
10074         cancel_lru_locks osc
10075         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10076         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10077 }
10078 run_test 66 "update inode blocks count on client ==============="
10079
10080 meminfo() {
10081         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10082 }
10083
10084 swap_used() {
10085         swapon -s | awk '($1 == "'$1'") { print $4 }'
10086 }
10087
10088 # bug5265, obdfilter oa2dentry return -ENOENT
10089 # #define OBD_FAIL_SRV_ENOENT 0x217
10090 test_69() {
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092         remote_ost_nodsh && skip "remote OST with nodsh"
10093
10094         f="$DIR/$tfile"
10095         $LFS setstripe -c 1 -i 0 $f
10096
10097         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10098
10099         do_facet ost1 lctl set_param fail_loc=0x217
10100         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10101         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10102
10103         do_facet ost1 lctl set_param fail_loc=0
10104         $DIRECTIO write $f 0 2 || error "write error"
10105
10106         cancel_lru_locks osc
10107         $DIRECTIO read $f 0 1 || error "read error"
10108
10109         do_facet ost1 lctl set_param fail_loc=0x217
10110         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10111
10112         do_facet ost1 lctl set_param fail_loc=0
10113         rm -f $f
10114 }
10115 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10116
10117 test_71() {
10118         test_mkdir $DIR/$tdir
10119         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10120         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10121 }
10122 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10123
10124 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10126         [ "$RUNAS_ID" = "$UID" ] &&
10127                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10128         # Check that testing environment is properly set up. Skip if not
10129         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10130                 skip_env "User $RUNAS_ID does not exist - skipping"
10131
10132         touch $DIR/$tfile
10133         chmod 777 $DIR/$tfile
10134         chmod ug+s $DIR/$tfile
10135         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10136                 error "$RUNAS dd $DIR/$tfile failed"
10137         # See if we are still setuid/sgid
10138         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10139                 error "S/gid is not dropped on write"
10140         # Now test that MDS is updated too
10141         cancel_lru_locks mdc
10142         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10143                 error "S/gid is not dropped on MDS"
10144         rm -f $DIR/$tfile
10145 }
10146 run_test 72a "Test that remove suid works properly (bug5695) ===="
10147
10148 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10149         local perm
10150
10151         [ "$RUNAS_ID" = "$UID" ] &&
10152                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10153         [ "$RUNAS_ID" -eq 0 ] &&
10154                 skip_env "RUNAS_ID = 0 -- skipping"
10155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10156         # Check that testing environment is properly set up. Skip if not
10157         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10158                 skip_env "User $RUNAS_ID does not exist - skipping"
10159
10160         touch $DIR/${tfile}-f{g,u}
10161         test_mkdir $DIR/${tfile}-dg
10162         test_mkdir $DIR/${tfile}-du
10163         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10164         chmod g+s $DIR/${tfile}-{f,d}g
10165         chmod u+s $DIR/${tfile}-{f,d}u
10166         for perm in 777 2777 4777; do
10167                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10168                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10169                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10170                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10171         done
10172         true
10173 }
10174 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10175
10176 # bug 3462 - multiple simultaneous MDC requests
10177 test_73() {
10178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10179
10180         test_mkdir $DIR/d73-1
10181         test_mkdir $DIR/d73-2
10182         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10183         pid1=$!
10184
10185         lctl set_param fail_loc=0x80000129
10186         $MULTIOP $DIR/d73-1/f73-2 Oc &
10187         sleep 1
10188         lctl set_param fail_loc=0
10189
10190         $MULTIOP $DIR/d73-2/f73-3 Oc &
10191         pid3=$!
10192
10193         kill -USR1 $pid1
10194         wait $pid1 || return 1
10195
10196         sleep 25
10197
10198         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10199         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10200         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10201
10202         rm -rf $DIR/d73-*
10203 }
10204 run_test 73 "multiple MDC requests (should not deadlock)"
10205
10206 test_74a() { # bug 6149, 6184
10207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10208
10209         touch $DIR/f74a
10210         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10211         #
10212         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10213         # will spin in a tight reconnection loop
10214         $LCTL set_param fail_loc=0x8000030e
10215         # get any lock that won't be difficult - lookup works.
10216         ls $DIR/f74a
10217         $LCTL set_param fail_loc=0
10218         rm -f $DIR/f74a
10219         true
10220 }
10221 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10222
10223 test_74b() { # bug 13310
10224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10225
10226         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10227         #
10228         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10229         # will spin in a tight reconnection loop
10230         $LCTL set_param fail_loc=0x8000030e
10231         # get a "difficult" lock
10232         touch $DIR/f74b
10233         $LCTL set_param fail_loc=0
10234         rm -f $DIR/f74b
10235         true
10236 }
10237 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10238
10239 test_74c() {
10240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10241
10242         #define OBD_FAIL_LDLM_NEW_LOCK
10243         $LCTL set_param fail_loc=0x319
10244         touch $DIR/$tfile && error "touch successful"
10245         $LCTL set_param fail_loc=0
10246         true
10247 }
10248 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10249
10250 slab_lic=/sys/kernel/slab/lustre_inode_cache
10251 num_objects() {
10252         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10253         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10254                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10255 }
10256
10257 test_76a() { # Now for b=20433, added originally in b=1443
10258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10259
10260         cancel_lru_locks osc
10261         # there may be some slab objects cached per core
10262         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10263         local before=$(num_objects)
10264         local count=$((512 * cpus))
10265         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10266         local margin=$((count / 10))
10267         if [[ -f $slab_lic/aliases ]]; then
10268                 local aliases=$(cat $slab_lic/aliases)
10269                 (( aliases > 0 )) && margin=$((margin * aliases))
10270         fi
10271
10272         echo "before slab objects: $before"
10273         for i in $(seq $count); do
10274                 touch $DIR/$tfile
10275                 rm -f $DIR/$tfile
10276         done
10277         cancel_lru_locks osc
10278         local after=$(num_objects)
10279         echo "created: $count, after slab objects: $after"
10280         # shared slab counts are not very accurate, allow significant margin
10281         # the main goal is that the cache growth is not permanently > $count
10282         while (( after > before + margin )); do
10283                 sleep 1
10284                 after=$(num_objects)
10285                 wait=$((wait + 1))
10286                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10287                 if (( wait > 60 )); then
10288                         error "inode slab grew from $before+$margin to $after"
10289                 fi
10290         done
10291 }
10292 run_test 76a "confirm clients recycle inodes properly ===="
10293
10294 test_76b() {
10295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10296         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10297
10298         local count=512
10299         local before=$(num_objects)
10300
10301         for i in $(seq $count); do
10302                 mkdir $DIR/$tdir
10303                 rmdir $DIR/$tdir
10304         done
10305
10306         local after=$(num_objects)
10307         local wait=0
10308
10309         while (( after > before )); do
10310                 sleep 1
10311                 after=$(num_objects)
10312                 wait=$((wait + 1))
10313                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10314                 if (( wait > 60 )); then
10315                         error "inode slab grew from $before to $after"
10316                 fi
10317         done
10318
10319         echo "slab objects before: $before, after: $after"
10320 }
10321 run_test 76b "confirm clients recycle directory inodes properly ===="
10322
10323 export ORIG_CSUM=""
10324 set_checksums()
10325 {
10326         # Note: in sptlrpc modes which enable its own bulk checksum, the
10327         # original crc32_le bulk checksum will be automatically disabled,
10328         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10329         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10330         # In this case set_checksums() will not be no-op, because sptlrpc
10331         # bulk checksum will be enabled all through the test.
10332
10333         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10334         lctl set_param -n osc.*.checksums $1
10335         return 0
10336 }
10337
10338 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10339                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10340 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10341                              tr -d [] | head -n1)}
10342 set_checksum_type()
10343 {
10344         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10345         rc=$?
10346         log "set checksum type to $1, rc = $rc"
10347         return $rc
10348 }
10349
10350 get_osc_checksum_type()
10351 {
10352         # arugment 1: OST name, like OST0000
10353         ost=$1
10354         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10355                         sed 's/.*\[\(.*\)\].*/\1/g')
10356         rc=$?
10357         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10358         echo $checksum_type
10359 }
10360
10361 F77_TMP=$TMP/f77-temp
10362 F77SZ=8
10363 setup_f77() {
10364         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10365                 error "error writing to $F77_TMP"
10366 }
10367
10368 test_77a() { # bug 10889
10369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10370         $GSS && skip_env "could not run with gss"
10371
10372         [ ! -f $F77_TMP ] && setup_f77
10373         set_checksums 1
10374         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10375         set_checksums 0
10376         rm -f $DIR/$tfile
10377 }
10378 run_test 77a "normal checksum read/write operation"
10379
10380 test_77b() { # bug 10889
10381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10382         $GSS && skip_env "could not run with gss"
10383
10384         [ ! -f $F77_TMP ] && setup_f77
10385         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10386         $LCTL set_param fail_loc=0x80000409
10387         set_checksums 1
10388
10389         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10390                 error "dd error: $?"
10391         $LCTL set_param fail_loc=0
10392
10393         for algo in $CKSUM_TYPES; do
10394                 cancel_lru_locks osc
10395                 set_checksum_type $algo
10396                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10397                 $LCTL set_param fail_loc=0x80000408
10398                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10399                 $LCTL set_param fail_loc=0
10400         done
10401         set_checksums 0
10402         set_checksum_type $ORIG_CSUM_TYPE
10403         rm -f $DIR/$tfile
10404 }
10405 run_test 77b "checksum error on client write, read"
10406
10407 cleanup_77c() {
10408         trap 0
10409         set_checksums 0
10410         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10411         $check_ost &&
10412                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10413         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10414         $check_ost && [ -n "$ost_file_prefix" ] &&
10415                 do_facet ost1 rm -f ${ost_file_prefix}\*
10416 }
10417
10418 test_77c() {
10419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10420         $GSS && skip_env "could not run with gss"
10421         remote_ost_nodsh && skip "remote OST with nodsh"
10422
10423         local bad1
10424         local osc_file_prefix
10425         local osc_file
10426         local check_ost=false
10427         local ost_file_prefix
10428         local ost_file
10429         local orig_cksum
10430         local dump_cksum
10431         local fid
10432
10433         # ensure corruption will occur on first OSS/OST
10434         $LFS setstripe -i 0 $DIR/$tfile
10435
10436         [ ! -f $F77_TMP ] && setup_f77
10437         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10438                 error "dd write error: $?"
10439         fid=$($LFS path2fid $DIR/$tfile)
10440
10441         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10442         then
10443                 check_ost=true
10444                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10445                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10446         else
10447                 echo "OSS do not support bulk pages dump upon error"
10448         fi
10449
10450         osc_file_prefix=$($LCTL get_param -n debug_path)
10451         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10452
10453         trap cleanup_77c EXIT
10454
10455         set_checksums 1
10456         # enable bulk pages dump upon error on Client
10457         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10458         # enable bulk pages dump upon error on OSS
10459         $check_ost &&
10460                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10461
10462         # flush Client cache to allow next read to reach OSS
10463         cancel_lru_locks osc
10464
10465         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10466         $LCTL set_param fail_loc=0x80000408
10467         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10468         $LCTL set_param fail_loc=0
10469
10470         rm -f $DIR/$tfile
10471
10472         # check cksum dump on Client
10473         osc_file=$(ls ${osc_file_prefix}*)
10474         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10475         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10476         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10477         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10478         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10479                      cksum)
10480         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10481         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10482                 error "dump content does not match on Client"
10483
10484         $check_ost || skip "No need to check cksum dump on OSS"
10485
10486         # check cksum dump on OSS
10487         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10488         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10489         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10490         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10491         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10492                 error "dump content does not match on OSS"
10493
10494         cleanup_77c
10495 }
10496 run_test 77c "checksum error on client read with debug"
10497
10498 test_77d() { # bug 10889
10499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10500         $GSS && skip_env "could not run with gss"
10501
10502         stack_trap "rm -f $DIR/$tfile"
10503         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10504         $LCTL set_param fail_loc=0x80000409
10505         set_checksums 1
10506         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10507                 error "direct write: rc=$?"
10508         $LCTL set_param fail_loc=0
10509         set_checksums 0
10510
10511         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10512         $LCTL set_param fail_loc=0x80000408
10513         set_checksums 1
10514         cancel_lru_locks osc
10515         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10516                 error "direct read: rc=$?"
10517         $LCTL set_param fail_loc=0
10518         set_checksums 0
10519 }
10520 run_test 77d "checksum error on OST direct write, read"
10521
10522 test_77f() { # bug 10889
10523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10524         $GSS && skip_env "could not run with gss"
10525
10526         set_checksums 1
10527         stack_trap "rm -f $DIR/$tfile"
10528         for algo in $CKSUM_TYPES; do
10529                 cancel_lru_locks osc
10530                 set_checksum_type $algo
10531                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10532                 $LCTL set_param fail_loc=0x409
10533                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10534                         error "direct write succeeded"
10535                 $LCTL set_param fail_loc=0
10536         done
10537         set_checksum_type $ORIG_CSUM_TYPE
10538         set_checksums 0
10539 }
10540 run_test 77f "repeat checksum error on write (expect error)"
10541
10542 test_77g() { # bug 10889
10543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10544         $GSS && skip_env "could not run with gss"
10545         remote_ost_nodsh && skip "remote OST with nodsh"
10546
10547         [ ! -f $F77_TMP ] && setup_f77
10548
10549         local file=$DIR/$tfile
10550         stack_trap "rm -f $file" EXIT
10551
10552         $LFS setstripe -c 1 -i 0 $file
10553         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10554         do_facet ost1 lctl set_param fail_loc=0x8000021a
10555         set_checksums 1
10556         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10557                 error "write error: rc=$?"
10558         do_facet ost1 lctl set_param fail_loc=0
10559         set_checksums 0
10560
10561         cancel_lru_locks osc
10562         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10563         do_facet ost1 lctl set_param fail_loc=0x8000021b
10564         set_checksums 1
10565         cmp $F77_TMP $file || error "file compare failed"
10566         do_facet ost1 lctl set_param fail_loc=0
10567         set_checksums 0
10568 }
10569 run_test 77g "checksum error on OST write, read"
10570
10571 test_77k() { # LU-10906
10572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10573         $GSS && skip_env "could not run with gss"
10574
10575         local cksum_param="osc.$FSNAME*.checksums"
10576         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10577         local checksum
10578         local i
10579
10580         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10581         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10582         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10583
10584         for i in 0 1; do
10585                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10586                         error "failed to set checksum=$i on MGS"
10587                 wait_update $HOSTNAME "$get_checksum" $i
10588                 #remount
10589                 echo "remount client, checksum should be $i"
10590                 remount_client $MOUNT || error "failed to remount client"
10591                 checksum=$(eval $get_checksum)
10592                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10593         done
10594         # remove persistent param to avoid races with checksum mountopt below
10595         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10596                 error "failed to delete checksum on MGS"
10597
10598         for opt in "checksum" "nochecksum"; do
10599                 #remount with mount option
10600                 echo "remount client with option $opt, checksum should be $i"
10601                 umount_client $MOUNT || error "failed to umount client"
10602                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10603                         error "failed to mount client with option '$opt'"
10604                 checksum=$(eval $get_checksum)
10605                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10606                 i=$((i - 1))
10607         done
10608
10609         remount_client $MOUNT || error "failed to remount client"
10610 }
10611 run_test 77k "enable/disable checksum correctly"
10612
10613 test_77l() {
10614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10615         $GSS && skip_env "could not run with gss"
10616
10617         set_checksums 1
10618         stack_trap "set_checksums $ORIG_CSUM" EXIT
10619         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10620
10621         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10622
10623         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10624         for algo in $CKSUM_TYPES; do
10625                 set_checksum_type $algo || error "fail to set checksum type $algo"
10626                 osc_algo=$(get_osc_checksum_type OST0000)
10627                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10628
10629                 # no locks, no reqs to let the connection idle
10630                 cancel_lru_locks osc
10631                 lru_resize_disable osc
10632                 wait_osc_import_state client ost1 IDLE
10633
10634                 # ensure ost1 is connected
10635                 stat $DIR/$tfile >/dev/null || error "can't stat"
10636                 wait_osc_import_state client ost1 FULL
10637
10638                 osc_algo=$(get_osc_checksum_type OST0000)
10639                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10640         done
10641         return 0
10642 }
10643 run_test 77l "preferred checksum type is remembered after reconnected"
10644
10645 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10646 rm -f $F77_TMP
10647 unset F77_TMP
10648
10649 test_77m() {
10650         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10651                 skip "Need at least version 2.14.52"
10652         local param=checksum_speed
10653
10654         $LCTL get_param $param || error "reading $param failed"
10655
10656         csum_speeds=$($LCTL get_param -n $param)
10657
10658         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10659                 error "known checksum types are missing"
10660 }
10661 run_test 77m "Verify checksum_speed is correctly read"
10662
10663 check_filefrag_77n() {
10664         local nr_ext=0
10665         local starts=()
10666         local ends=()
10667
10668         while read extidx a b start end rest; do
10669                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10670                         nr_ext=$(( $nr_ext + 1 ))
10671                         starts+=( ${start%..} )
10672                         ends+=( ${end%:} )
10673                 fi
10674         done < <( filefrag -sv $1 )
10675
10676         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10677         return 1
10678 }
10679
10680 test_77n() {
10681         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10682
10683         touch $DIR/$tfile
10684         $TRUNCATE $DIR/$tfile 0
10685         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10686         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10687         check_filefrag_77n $DIR/$tfile ||
10688                 skip "$tfile blocks not contiguous around hole"
10689
10690         set_checksums 1
10691         stack_trap "set_checksums $ORIG_CSUM" EXIT
10692         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10693         stack_trap "rm -f $DIR/$tfile"
10694
10695         for algo in $CKSUM_TYPES; do
10696                 if [[ "$algo" =~ ^t10 ]]; then
10697                         set_checksum_type $algo ||
10698                                 error "fail to set checksum type $algo"
10699                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10700                                 error "fail to read $tfile with $algo"
10701                 fi
10702         done
10703         rm -f $DIR/$tfile
10704         return 0
10705 }
10706 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10707
10708 test_77o() {
10709         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10710                 skip "Need MDS version at least 2.14.55"
10711         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10712                 skip "Need OST version at least 2.14.55"
10713         local ofd=obdfilter
10714         local mdt=mdt
10715
10716         # print OST checksum_type
10717         echo "$ofd.$FSNAME-*.checksum_type:"
10718         do_nodes $(comma_list $(osts_nodes)) \
10719                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10720
10721         # print MDT checksum_type
10722         echo "$mdt.$FSNAME-*.checksum_type:"
10723         do_nodes $(comma_list $(mdts_nodes)) \
10724                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10725
10726         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10727                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10728
10729         (( $o_count == $OSTCOUNT )) ||
10730                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10731
10732         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10733                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10734
10735         (( $m_count == $MDSCOUNT )) ||
10736                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10737 }
10738 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10739
10740 cleanup_test_78() {
10741         trap 0
10742         rm -f $DIR/$tfile
10743 }
10744
10745 test_78() { # bug 10901
10746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10747         remote_ost || skip_env "local OST"
10748
10749         NSEQ=5
10750         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10751         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10752         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10753         echo "MemTotal: $MEMTOTAL"
10754
10755         # reserve 256MB of memory for the kernel and other running processes,
10756         # and then take 1/2 of the remaining memory for the read/write buffers.
10757         if [ $MEMTOTAL -gt 512 ] ;then
10758                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10759         else
10760                 # for those poor memory-starved high-end clusters...
10761                 MEMTOTAL=$((MEMTOTAL / 2))
10762         fi
10763         echo "Mem to use for directio: $MEMTOTAL"
10764
10765         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10766         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10767         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10768         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10769                 head -n1)
10770         echo "Smallest OST: $SMALLESTOST"
10771         [[ $SMALLESTOST -lt 10240 ]] &&
10772                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10773
10774         trap cleanup_test_78 EXIT
10775
10776         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10777                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10778
10779         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10780         echo "File size: $F78SIZE"
10781         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10782         for i in $(seq 1 $NSEQ); do
10783                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10784                 echo directIO rdwr round $i of $NSEQ
10785                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10786         done
10787
10788         cleanup_test_78
10789 }
10790 run_test 78 "handle large O_DIRECT writes correctly ============"
10791
10792 test_79() { # bug 12743
10793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10794
10795         wait_delete_completed
10796
10797         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10798         BKFREE=$(calc_osc_kbytes kbytesfree)
10799         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10800
10801         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10802         DFTOTAL=`echo $STRING | cut -d, -f1`
10803         DFUSED=`echo $STRING  | cut -d, -f2`
10804         DFAVAIL=`echo $STRING | cut -d, -f3`
10805         DFFREE=$(($DFTOTAL - $DFUSED))
10806
10807         ALLOWANCE=$((64 * $OSTCOUNT))
10808
10809         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10810            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10811                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10812         fi
10813         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10814            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10815                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10816         fi
10817         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10818            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10819                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10820         fi
10821 }
10822 run_test 79 "df report consistency check ======================="
10823
10824 test_80() { # bug 10718
10825         remote_ost_nodsh && skip "remote OST with nodsh"
10826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10827
10828         # relax strong synchronous semantics for slow backends like ZFS
10829         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10830                 local soc="obdfilter.*.sync_lock_cancel"
10831                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10832
10833                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10834                 if [ -z "$save" ]; then
10835                         soc="obdfilter.*.sync_on_lock_cancel"
10836                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10837                 fi
10838
10839                 if [ "$save" != "never" ]; then
10840                         local hosts=$(comma_list $(osts_nodes))
10841
10842                         do_nodes $hosts $LCTL set_param $soc=never
10843                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10844                 fi
10845         fi
10846
10847         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10848         sync; sleep 1; sync
10849         local before=$(date +%s)
10850         cancel_lru_locks osc
10851         local after=$(date +%s)
10852         local diff=$((after - before))
10853         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10854
10855         rm -f $DIR/$tfile
10856 }
10857 run_test 80 "Page eviction is equally fast at high offsets too"
10858
10859 test_81a() { # LU-456
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861         remote_ost_nodsh && skip "remote OST with nodsh"
10862
10863         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10864         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10865         do_facet ost1 lctl set_param fail_loc=0x80000228
10866
10867         # write should trigger a retry and success
10868         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10869         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10870         RC=$?
10871         if [ $RC -ne 0 ] ; then
10872                 error "write should success, but failed for $RC"
10873         fi
10874 }
10875 run_test 81a "OST should retry write when get -ENOSPC ==============="
10876
10877 test_81b() { # LU-456
10878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10879         remote_ost_nodsh && skip "remote OST with nodsh"
10880
10881         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10882         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10883         do_facet ost1 lctl set_param fail_loc=0x228
10884
10885         # write should retry several times and return -ENOSPC finally
10886         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10887         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10888         RC=$?
10889         ENOSPC=28
10890         if [ $RC -ne $ENOSPC ] ; then
10891                 error "dd should fail for -ENOSPC, but succeed."
10892         fi
10893 }
10894 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10895
10896 test_99() {
10897         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10898
10899         test_mkdir $DIR/$tdir.cvsroot
10900         chown $RUNAS_ID $DIR/$tdir.cvsroot
10901
10902         cd $TMP
10903         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10904
10905         cd /etc/init.d
10906         # some versions of cvs import exit(1) when asked to import links or
10907         # files they can't read.  ignore those files.
10908         local toignore=$(find . -type l -printf '-I %f\n' -o \
10909                          ! -perm /4 -printf '-I %f\n')
10910         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10911                 $tdir.reposname vtag rtag
10912
10913         cd $DIR
10914         test_mkdir $DIR/$tdir.reposname
10915         chown $RUNAS_ID $DIR/$tdir.reposname
10916         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10917
10918         cd $DIR/$tdir.reposname
10919         $RUNAS touch foo99
10920         $RUNAS cvs add -m 'addmsg' foo99
10921         $RUNAS cvs update
10922         $RUNAS cvs commit -m 'nomsg' foo99
10923         rm -fr $DIR/$tdir.cvsroot
10924 }
10925 run_test 99 "cvs strange file/directory operations"
10926
10927 test_100() {
10928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10929         [[ "$NETTYPE" =~ tcp ]] ||
10930                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10931         remote_ost_nodsh && skip "remote OST with nodsh"
10932         remote_mds_nodsh && skip "remote MDS with nodsh"
10933         remote_servers ||
10934                 skip "useless for local single node setup"
10935
10936         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10937                 [ "$PROT" != "tcp" ] && continue
10938                 RPORT=$(echo $REMOTE | cut -d: -f2)
10939                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10940
10941                 rc=0
10942                 LPORT=`echo $LOCAL | cut -d: -f2`
10943                 if [ $LPORT -ge 1024 ]; then
10944                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10945                         netstat -tna
10946                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10947                 fi
10948         done
10949         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10950 }
10951 run_test 100 "check local port using privileged port ==========="
10952
10953 function get_named_value()
10954 {
10955     local tag=$1
10956
10957     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10958 }
10959
10960 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10961                    awk '/^max_cached_mb/ { print $2 }')
10962
10963 cleanup_101a() {
10964         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10965         trap 0
10966 }
10967
10968 test_101a() {
10969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10970
10971         local s
10972         local discard
10973         local nreads=10000
10974         local cache_limit=32
10975
10976         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10977         trap cleanup_101a EXIT
10978         $LCTL set_param -n llite.*.read_ahead_stats=0
10979         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10980
10981         #
10982         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10983         #
10984         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10985         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10986
10987         discard=0
10988         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10989                    get_named_value 'read.but.discarded'); do
10990                         discard=$(($discard + $s))
10991         done
10992         cleanup_101a
10993
10994         $LCTL get_param osc.*-osc*.rpc_stats
10995         $LCTL get_param llite.*.read_ahead_stats
10996
10997         # Discard is generally zero, but sometimes a few random reads line up
10998         # and trigger larger readahead, which is wasted & leads to discards.
10999         if [[ $(($discard)) -gt $nreads ]]; then
11000                 error "too many ($discard) discarded pages"
11001         fi
11002         rm -f $DIR/$tfile || true
11003 }
11004 run_test 101a "check read-ahead for random reads"
11005
11006 setup_test101bc() {
11007         test_mkdir $DIR/$tdir
11008         local ssize=$1
11009         local FILE_LENGTH=$2
11010         STRIPE_OFFSET=0
11011
11012         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11013
11014         local list=$(comma_list $(osts_nodes))
11015         set_osd_param $list '' read_cache_enable 0
11016         set_osd_param $list '' writethrough_cache_enable 0
11017
11018         trap cleanup_test101bc EXIT
11019         # prepare the read-ahead file
11020         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11021
11022         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11023                                 count=$FILE_SIZE_MB 2> /dev/null
11024
11025 }
11026
11027 cleanup_test101bc() {
11028         trap 0
11029         rm -rf $DIR/$tdir
11030         rm -f $DIR/$tfile
11031
11032         local list=$(comma_list $(osts_nodes))
11033         set_osd_param $list '' read_cache_enable 1
11034         set_osd_param $list '' writethrough_cache_enable 1
11035 }
11036
11037 calc_total() {
11038         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11039 }
11040
11041 ra_check_101() {
11042         local read_size=$1
11043         local stripe_size=$2
11044         local stride_length=$((stripe_size / read_size))
11045         local stride_width=$((stride_length * OSTCOUNT))
11046         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11047                                 (stride_width - stride_length) ))
11048         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11049                   get_named_value 'read.but.discarded' | calc_total)
11050
11051         if [[ $discard -gt $discard_limit ]]; then
11052                 $LCTL get_param llite.*.read_ahead_stats
11053                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11054         else
11055                 echo "Read-ahead success for size ${read_size}"
11056         fi
11057 }
11058
11059 test_101b() {
11060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11061         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11062
11063         local STRIPE_SIZE=1048576
11064         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11065
11066         if [ $SLOW == "yes" ]; then
11067                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11068         else
11069                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11070         fi
11071
11072         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11073
11074         # prepare the read-ahead file
11075         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11076         cancel_lru_locks osc
11077         for BIDX in 2 4 8 16 32 64 128 256
11078         do
11079                 local BSIZE=$((BIDX*4096))
11080                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11081                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11082                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11083                 $LCTL set_param -n llite.*.read_ahead_stats=0
11084                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11085                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11086                 cancel_lru_locks osc
11087                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11088         done
11089         cleanup_test101bc
11090         true
11091 }
11092 run_test 101b "check stride-io mode read-ahead ================="
11093
11094 test_101c() {
11095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11096
11097         local STRIPE_SIZE=1048576
11098         local FILE_LENGTH=$((STRIPE_SIZE*100))
11099         local nreads=10000
11100         local rsize=65536
11101         local osc_rpc_stats
11102
11103         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11104
11105         cancel_lru_locks osc
11106         $LCTL set_param osc.*.rpc_stats=0
11107         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11108         $LCTL get_param osc.*.rpc_stats
11109         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11110                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11111                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11112                 local size
11113
11114                 if [ $lines -le 20 ]; then
11115                         echo "continue debug"
11116                         continue
11117                 fi
11118                 for size in 1 2 4 8; do
11119                         local rpc=$(echo "$stats" |
11120                                     awk '($1 == "'$size':") {print $2; exit; }')
11121                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11122                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11123                 done
11124                 echo "$osc_rpc_stats check passed!"
11125         done
11126         cleanup_test101bc
11127         true
11128 }
11129 run_test 101c "check stripe_size aligned read-ahead"
11130
11131 test_101d() {
11132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11133
11134         local file=$DIR/$tfile
11135         local sz_MB=${FILESIZE_101d:-80}
11136         local ra_MB=${READAHEAD_MB:-40}
11137
11138         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11139         [ $free_MB -lt $sz_MB ] &&
11140                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11141
11142         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11143         $LFS setstripe -c -1 $file || error "setstripe failed"
11144
11145         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11146         echo Cancel LRU locks on lustre client to flush the client cache
11147         cancel_lru_locks osc
11148
11149         echo Disable read-ahead
11150         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11151         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11152         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11153         $LCTL get_param -n llite.*.max_read_ahead_mb
11154
11155         echo "Reading the test file $file with read-ahead disabled"
11156         local sz_KB=$((sz_MB * 1024 / 4))
11157         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11158         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11159         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11160                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11161
11162         echo "Cancel LRU locks on lustre client to flush the client cache"
11163         cancel_lru_locks osc
11164         echo Enable read-ahead with ${ra_MB}MB
11165         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11166
11167         echo "Reading the test file $file with read-ahead enabled"
11168         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11169                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11170
11171         echo "read-ahead disabled time read $raOFF"
11172         echo "read-ahead enabled time read $raON"
11173
11174         rm -f $file
11175         wait_delete_completed
11176
11177         # use awk for this check instead of bash because it handles decimals
11178         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11179                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11180 }
11181 run_test 101d "file read with and without read-ahead enabled"
11182
11183 test_101e() {
11184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11185
11186         local file=$DIR/$tfile
11187         local size_KB=500  #KB
11188         local count=100
11189         local bsize=1024
11190
11191         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11192         local need_KB=$((count * size_KB))
11193         [[ $free_KB -le $need_KB ]] &&
11194                 skip_env "Need free space $need_KB, have $free_KB"
11195
11196         echo "Creating $count ${size_KB}K test files"
11197         for ((i = 0; i < $count; i++)); do
11198                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11199         done
11200
11201         echo "Cancel LRU locks on lustre client to flush the client cache"
11202         cancel_lru_locks $OSC
11203
11204         echo "Reset readahead stats"
11205         $LCTL set_param -n llite.*.read_ahead_stats=0
11206
11207         for ((i = 0; i < $count; i++)); do
11208                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11209         done
11210
11211         $LCTL get_param llite.*.max_cached_mb
11212         $LCTL get_param llite.*.read_ahead_stats
11213         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11214                      get_named_value 'misses' | calc_total)
11215
11216         for ((i = 0; i < $count; i++)); do
11217                 rm -rf $file.$i 2>/dev/null
11218         done
11219
11220         #10000 means 20% reads are missing in readahead
11221         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11222 }
11223 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11224
11225 test_101f() {
11226         which iozone || skip_env "no iozone installed"
11227
11228         local old_debug=$($LCTL get_param debug)
11229         old_debug=${old_debug#*=}
11230         $LCTL set_param debug="reada mmap"
11231
11232         # create a test file
11233         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11234
11235         echo Cancel LRU locks on lustre client to flush the client cache
11236         cancel_lru_locks osc
11237
11238         echo Reset readahead stats
11239         $LCTL set_param -n llite.*.read_ahead_stats=0
11240
11241         echo mmap read the file with small block size
11242         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11243                 > /dev/null 2>&1
11244
11245         echo checking missing pages
11246         $LCTL get_param llite.*.read_ahead_stats
11247         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11248                         get_named_value 'misses' | calc_total)
11249
11250         $LCTL set_param debug="$old_debug"
11251         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11252         rm -f $DIR/$tfile
11253 }
11254 run_test 101f "check mmap read performance"
11255
11256 test_101g_brw_size_test() {
11257         local mb=$1
11258         local pages=$((mb * 1048576 / PAGE_SIZE))
11259         local file=$DIR/$tfile
11260
11261         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11262                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11263         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11264                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11265                         return 2
11266         done
11267
11268         stack_trap "rm -f $file" EXIT
11269         $LCTL set_param -n osc.*.rpc_stats=0
11270
11271         # 10 RPCs should be enough for the test
11272         local count=10
11273         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11274                 { error "dd write ${mb} MB blocks failed"; return 3; }
11275         cancel_lru_locks osc
11276         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11277                 { error "dd write ${mb} MB blocks failed"; return 4; }
11278
11279         # calculate number of full-sized read and write RPCs
11280         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11281                 sed -n '/pages per rpc/,/^$/p' |
11282                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11283                 END { print reads,writes }'))
11284         # allow one extra full-sized read RPC for async readahead
11285         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11286                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11287         [[ ${rpcs[1]} == $count ]] ||
11288                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11289 }
11290
11291 test_101g() {
11292         remote_ost_nodsh && skip "remote OST with nodsh"
11293
11294         local rpcs
11295         local osts=$(get_facets OST)
11296         local list=$(comma_list $(osts_nodes))
11297         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11298         local brw_size="obdfilter.*.brw_size"
11299
11300         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11301
11302         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11303
11304         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11305                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11306                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11307            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11308                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11309                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11310
11311                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11312                         suffix="M"
11313
11314                 if [[ $orig_mb -lt 16 ]]; then
11315                         save_lustre_params $osts "$brw_size" > $p
11316                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11317                                 error "set 16MB RPC size failed"
11318
11319                         echo "remount client to enable new RPC size"
11320                         remount_client $MOUNT || error "remount_client failed"
11321                 fi
11322
11323                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11324                 # should be able to set brw_size=12, but no rpc_stats for that
11325                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11326         fi
11327
11328         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11329
11330         if [[ $orig_mb -lt 16 ]]; then
11331                 restore_lustre_params < $p
11332                 remount_client $MOUNT || error "remount_client restore failed"
11333         fi
11334
11335         rm -f $p $DIR/$tfile
11336 }
11337 run_test 101g "Big bulk(4/16 MiB) readahead"
11338
11339 test_101h() {
11340         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11341
11342         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11343                 error "dd 70M file failed"
11344         echo Cancel LRU locks on lustre client to flush the client cache
11345         cancel_lru_locks osc
11346
11347         echo "Reset readahead stats"
11348         $LCTL set_param -n llite.*.read_ahead_stats 0
11349
11350         echo "Read 10M of data but cross 64M bundary"
11351         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11352         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11353                      get_named_value 'misses' | calc_total)
11354         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11355         rm -f $p $DIR/$tfile
11356 }
11357 run_test 101h "Readahead should cover current read window"
11358
11359 test_101i() {
11360         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11361                 error "dd 10M file failed"
11362
11363         local max_per_file_mb=$($LCTL get_param -n \
11364                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11365         cancel_lru_locks osc
11366         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11367         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11368                 error "set max_read_ahead_per_file_mb to 1 failed"
11369
11370         echo "Reset readahead stats"
11371         $LCTL set_param llite.*.read_ahead_stats=0
11372
11373         dd if=$DIR/$tfile of=/dev/null bs=2M
11374
11375         $LCTL get_param llite.*.read_ahead_stats
11376         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11377                      awk '/misses/ { print $2 }')
11378         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11379         rm -f $DIR/$tfile
11380 }
11381 run_test 101i "allow current readahead to exceed reservation"
11382
11383 test_101j() {
11384         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11385                 error "setstripe $DIR/$tfile failed"
11386         local file_size=$((1048576 * 16))
11387         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11388         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11389
11390         echo Disable read-ahead
11391         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11392
11393         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11394         for blk in $PAGE_SIZE 1048576 $file_size; do
11395                 cancel_lru_locks osc
11396                 echo "Reset readahead stats"
11397                 $LCTL set_param -n llite.*.read_ahead_stats=0
11398                 local count=$(($file_size / $blk))
11399                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11400                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11401                              get_named_value 'failed.to.fast.read' | calc_total)
11402                 $LCTL get_param -n llite.*.read_ahead_stats
11403                 [ $miss -eq $count ] || error "expected $count got $miss"
11404         done
11405
11406         rm -f $p $DIR/$tfile
11407 }
11408 run_test 101j "A complete read block should be submitted when no RA"
11409
11410 test_readahead_base() {
11411         local file=$DIR/$tfile
11412         local size=$1
11413         local iosz
11414         local ramax
11415         local ranum
11416
11417         $LCTL set_param -n llite.*.read_ahead_stats=0
11418         # The first page is not accounted into readahead
11419         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11420         iosz=$(((size + 1048575) / 1048576 * 1048576))
11421         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11422
11423         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11424         fallocate -l $size $file || error "failed to fallocate $file"
11425         cancel_lru_locks osc
11426         $MULTIOP $file or${iosz}c || error "failed to read $file"
11427         $LCTL get_param -n llite.*.read_ahead_stats
11428         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11429                 awk '/readahead.pages/ { print $7 }' | calc_total)
11430         (( $ranum <= $ramax )) ||
11431                 error "read-ahead pages is $ranum more than $ramax"
11432         rm -rf $file || error "failed to remove $file"
11433 }
11434
11435 test_101m()
11436 {
11437         local file=$DIR/$tfile
11438         local ramax
11439         local ranum
11440         local size
11441         local iosz
11442
11443         check_set_fallocate_or_skip
11444         stack_trap "rm -f $file" EXIT
11445
11446         test_readahead_base 4096
11447
11448         # file size: 16K = 16384
11449         test_readahead_base 16384
11450         test_readahead_base 16385
11451         test_readahead_base 16383
11452
11453         # file size: 1M + 1 = 1048576 + 1
11454         test_readahead_base 1048577
11455         # file size: 1M + 16K
11456         test_readahead_base $((1048576 + 16384))
11457
11458         # file size: stripe_size * (stripe_count - 1) + 16K
11459         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11460         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11461         # file size: stripe_size * stripe_count + 16K
11462         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11463         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11464         # file size: 2 * stripe_size * stripe_count + 16K
11465         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11466         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11467 }
11468 run_test 101m "read ahead for small file and last stripe of the file"
11469
11470 setup_test102() {
11471         test_mkdir $DIR/$tdir
11472         chown $RUNAS_ID $DIR/$tdir
11473         STRIPE_SIZE=65536
11474         STRIPE_OFFSET=1
11475         STRIPE_COUNT=$OSTCOUNT
11476         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11477
11478         trap cleanup_test102 EXIT
11479         cd $DIR
11480         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11481         cd $DIR/$tdir
11482         for num in 1 2 3 4; do
11483                 for count in $(seq 1 $STRIPE_COUNT); do
11484                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11485                                 local size=`expr $STRIPE_SIZE \* $num`
11486                                 local file=file"$num-$idx-$count"
11487                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11488                         done
11489                 done
11490         done
11491
11492         cd $DIR
11493         $1 tar cf $TMP/f102.tar $tdir --xattrs
11494 }
11495
11496 cleanup_test102() {
11497         trap 0
11498         rm -f $TMP/f102.tar
11499         rm -rf $DIR/d0.sanity/d102
11500 }
11501
11502 test_102a() {
11503         [ "$UID" != 0 ] && skip "must run as root"
11504         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11505                 skip_env "must have user_xattr"
11506
11507         [ -z "$(which setfattr 2>/dev/null)" ] &&
11508                 skip_env "could not find setfattr"
11509
11510         local testfile=$DIR/$tfile
11511
11512         touch $testfile
11513         echo "set/get xattr..."
11514         setfattr -n trusted.name1 -v value1 $testfile ||
11515                 error "setfattr -n trusted.name1=value1 $testfile failed"
11516         getfattr -n trusted.name1 $testfile 2> /dev/null |
11517           grep "trusted.name1=.value1" ||
11518                 error "$testfile missing trusted.name1=value1"
11519
11520         setfattr -n user.author1 -v author1 $testfile ||
11521                 error "setfattr -n user.author1=author1 $testfile failed"
11522         getfattr -n user.author1 $testfile 2> /dev/null |
11523           grep "user.author1=.author1" ||
11524                 error "$testfile missing trusted.author1=author1"
11525
11526         echo "listxattr..."
11527         setfattr -n trusted.name2 -v value2 $testfile ||
11528                 error "$testfile unable to set trusted.name2"
11529         setfattr -n trusted.name3 -v value3 $testfile ||
11530                 error "$testfile unable to set trusted.name3"
11531         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11532             grep "trusted.name" | wc -l) -eq 3 ] ||
11533                 error "$testfile missing 3 trusted.name xattrs"
11534
11535         setfattr -n user.author2 -v author2 $testfile ||
11536                 error "$testfile unable to set user.author2"
11537         setfattr -n user.author3 -v author3 $testfile ||
11538                 error "$testfile unable to set user.author3"
11539         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11540             grep "user.author" | wc -l) -eq 3 ] ||
11541                 error "$testfile missing 3 user.author xattrs"
11542
11543         echo "remove xattr..."
11544         setfattr -x trusted.name1 $testfile ||
11545                 error "$testfile error deleting trusted.name1"
11546         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11547                 error "$testfile did not delete trusted.name1 xattr"
11548
11549         setfattr -x user.author1 $testfile ||
11550                 error "$testfile error deleting user.author1"
11551         echo "set lustre special xattr ..."
11552         $LFS setstripe -c1 $testfile
11553         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11554                 awk -F "=" '/trusted.lov/ { print $2 }' )
11555         setfattr -n "trusted.lov" -v $lovea $testfile ||
11556                 error "$testfile doesn't ignore setting trusted.lov again"
11557         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11558                 error "$testfile allow setting invalid trusted.lov"
11559         rm -f $testfile
11560 }
11561 run_test 102a "user xattr test =================================="
11562
11563 check_102b_layout() {
11564         local layout="$*"
11565         local testfile=$DIR/$tfile
11566
11567         echo "test layout '$layout'"
11568         $LFS setstripe $layout $testfile || error "setstripe failed"
11569         $LFS getstripe -y $testfile
11570
11571         echo "get/set/list trusted.lov xattr ..." # b=10930
11572         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11573         [[ "$value" =~ "trusted.lov" ]] ||
11574                 error "can't get trusted.lov from $testfile"
11575         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11576                 error "getstripe failed"
11577
11578         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11579
11580         value=$(cut -d= -f2 <<<$value)
11581         # LU-13168: truncated xattr should fail if short lov_user_md header
11582         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11583                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11584         for len in $lens; do
11585                 echo "setfattr $len $testfile.2"
11586                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11587                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11588         done
11589         local stripe_size=$($LFS getstripe -S $testfile.2)
11590         local stripe_count=$($LFS getstripe -c $testfile.2)
11591         [[ $stripe_size -eq 65536 ]] ||
11592                 error "stripe size $stripe_size != 65536"
11593         [[ $stripe_count -eq $stripe_count_orig ]] ||
11594                 error "stripe count $stripe_count != $stripe_count_orig"
11595         rm $testfile $testfile.2
11596 }
11597
11598 test_102b() {
11599         [ -z "$(which setfattr 2>/dev/null)" ] &&
11600                 skip_env "could not find setfattr"
11601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11602
11603         # check plain layout
11604         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11605
11606         # and also check composite layout
11607         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11608
11609 }
11610 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11611
11612 test_102c() {
11613         [ -z "$(which setfattr 2>/dev/null)" ] &&
11614                 skip_env "could not find setfattr"
11615         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11616
11617         # b10930: get/set/list lustre.lov xattr
11618         echo "get/set/list lustre.lov xattr ..."
11619         test_mkdir $DIR/$tdir
11620         chown $RUNAS_ID $DIR/$tdir
11621         local testfile=$DIR/$tdir/$tfile
11622         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11623                 error "setstripe failed"
11624         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11625                 error "getstripe failed"
11626         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11627         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11628
11629         local testfile2=${testfile}2
11630         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11631                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11632
11633         $RUNAS $MCREATE $testfile2
11634         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11635         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11636         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11637         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11638         [ $stripe_count -eq $STRIPECOUNT ] ||
11639                 error "stripe count $stripe_count != $STRIPECOUNT"
11640 }
11641 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11642
11643 compare_stripe_info1() {
11644         local stripe_index_all_zero=true
11645
11646         for num in 1 2 3 4; do
11647                 for count in $(seq 1 $STRIPE_COUNT); do
11648                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11649                                 local size=$((STRIPE_SIZE * num))
11650                                 local file=file"$num-$offset-$count"
11651                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11652                                 [[ $stripe_size -ne $size ]] &&
11653                                     error "$file: size $stripe_size != $size"
11654                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11655                                 # allow fewer stripes to be created, ORI-601
11656                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11657                                     error "$file: count $stripe_count != $count"
11658                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11659                                 [[ $stripe_index -ne 0 ]] &&
11660                                         stripe_index_all_zero=false
11661                         done
11662                 done
11663         done
11664         $stripe_index_all_zero &&
11665                 error "all files are being extracted starting from OST index 0"
11666         return 0
11667 }
11668
11669 have_xattrs_include() {
11670         tar --help | grep -q xattrs-include &&
11671                 echo --xattrs-include="lustre.*"
11672 }
11673
11674 test_102d() {
11675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11676         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11677
11678         XINC=$(have_xattrs_include)
11679         setup_test102
11680         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11681         cd $DIR/$tdir/$tdir
11682         compare_stripe_info1
11683 }
11684 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11685
11686 test_102f() {
11687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11688         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11689
11690         XINC=$(have_xattrs_include)
11691         setup_test102
11692         test_mkdir $DIR/$tdir.restore
11693         cd $DIR
11694         tar cf - --xattrs $tdir | tar xf - \
11695                 -C $DIR/$tdir.restore --xattrs $XINC
11696         cd $DIR/$tdir.restore/$tdir
11697         compare_stripe_info1
11698 }
11699 run_test 102f "tar copy files, not keep osts"
11700
11701 grow_xattr() {
11702         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11703                 skip "must have user_xattr"
11704         [ -z "$(which setfattr 2>/dev/null)" ] &&
11705                 skip_env "could not find setfattr"
11706         [ -z "$(which getfattr 2>/dev/null)" ] &&
11707                 skip_env "could not find getfattr"
11708
11709         local xsize=${1:-1024}  # in bytes
11710         local file=$DIR/$tfile
11711         local value="$(generate_string $xsize)"
11712         local xbig=trusted.big
11713         local toobig=$2
11714
11715         touch $file
11716         log "save $xbig on $file"
11717         if [ -z "$toobig" ]
11718         then
11719                 setfattr -n $xbig -v $value $file ||
11720                         error "saving $xbig on $file failed"
11721         else
11722                 setfattr -n $xbig -v $value $file &&
11723                         error "saving $xbig on $file succeeded"
11724                 return 0
11725         fi
11726
11727         local orig=$(get_xattr_value $xbig $file)
11728         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11729
11730         local xsml=trusted.sml
11731         log "save $xsml on $file"
11732         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11733
11734         local new=$(get_xattr_value $xbig $file)
11735         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11736
11737         log "grow $xsml on $file"
11738         setfattr -n $xsml -v "$value" $file ||
11739                 error "growing $xsml on $file failed"
11740
11741         new=$(get_xattr_value $xbig $file)
11742         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11743         log "$xbig still valid after growing $xsml"
11744
11745         rm -f $file
11746 }
11747
11748 test_102h() { # bug 15777
11749         grow_xattr 1024
11750 }
11751 run_test 102h "grow xattr from inside inode to external block"
11752
11753 test_102ha() {
11754         large_xattr_enabled || skip_env "ea_inode feature disabled"
11755
11756         echo "setting xattr of max xattr size: $(max_xattr_size)"
11757         grow_xattr $(max_xattr_size)
11758
11759         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11760         echo "This should fail:"
11761         grow_xattr $(($(max_xattr_size) + 10)) 1
11762 }
11763 run_test 102ha "grow xattr from inside inode to external inode"
11764
11765 test_102i() { # bug 17038
11766         [ -z "$(which getfattr 2>/dev/null)" ] &&
11767                 skip "could not find getfattr"
11768
11769         touch $DIR/$tfile
11770         ln -s $DIR/$tfile $DIR/${tfile}link
11771         getfattr -n trusted.lov $DIR/$tfile ||
11772                 error "lgetxattr on $DIR/$tfile failed"
11773         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11774                 grep -i "no such attr" ||
11775                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11776         rm -f $DIR/$tfile $DIR/${tfile}link
11777 }
11778 run_test 102i "lgetxattr test on symbolic link ============"
11779
11780 test_102j() {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11783
11784         XINC=$(have_xattrs_include)
11785         setup_test102 "$RUNAS"
11786         chown $RUNAS_ID $DIR/$tdir
11787         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11788         cd $DIR/$tdir/$tdir
11789         compare_stripe_info1 "$RUNAS"
11790 }
11791 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11792
11793 test_102k() {
11794         [ -z "$(which setfattr 2>/dev/null)" ] &&
11795                 skip "could not find setfattr"
11796
11797         touch $DIR/$tfile
11798         # b22187 just check that does not crash for regular file.
11799         setfattr -n trusted.lov $DIR/$tfile
11800         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11801         local test_kdir=$DIR/$tdir
11802         test_mkdir $test_kdir
11803         local default_size=$($LFS getstripe -S $test_kdir)
11804         local default_count=$($LFS getstripe -c $test_kdir)
11805         local default_offset=$($LFS getstripe -i $test_kdir)
11806         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11807                 error 'dir setstripe failed'
11808         setfattr -n trusted.lov $test_kdir
11809         local stripe_size=$($LFS getstripe -S $test_kdir)
11810         local stripe_count=$($LFS getstripe -c $test_kdir)
11811         local stripe_offset=$($LFS getstripe -i $test_kdir)
11812         [ $stripe_size -eq $default_size ] ||
11813                 error "stripe size $stripe_size != $default_size"
11814         [ $stripe_count -eq $default_count ] ||
11815                 error "stripe count $stripe_count != $default_count"
11816         [ $stripe_offset -eq $default_offset ] ||
11817                 error "stripe offset $stripe_offset != $default_offset"
11818         rm -rf $DIR/$tfile $test_kdir
11819 }
11820 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11821
11822 test_102l() {
11823         [ -z "$(which getfattr 2>/dev/null)" ] &&
11824                 skip "could not find getfattr"
11825
11826         # LU-532 trusted. xattr is invisible to non-root
11827         local testfile=$DIR/$tfile
11828
11829         touch $testfile
11830
11831         echo "listxattr as user..."
11832         chown $RUNAS_ID $testfile
11833         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11834             grep -q "trusted" &&
11835                 error "$testfile trusted xattrs are user visible"
11836
11837         return 0;
11838 }
11839 run_test 102l "listxattr size test =================================="
11840
11841 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11842         local path=$DIR/$tfile
11843         touch $path
11844
11845         listxattr_size_check $path || error "listattr_size_check $path failed"
11846 }
11847 run_test 102m "Ensure listxattr fails on small bufffer ========"
11848
11849 cleanup_test102
11850
11851 getxattr() { # getxattr path name
11852         # Return the base64 encoding of the value of xattr name on path.
11853         local path=$1
11854         local name=$2
11855
11856         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11857         # file: $path
11858         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11859         #
11860         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11861
11862         getfattr --absolute-names --encoding=base64 --name=$name $path |
11863                 awk -F= -v name=$name '$1 == name {
11864                         print substr($0, index($0, "=") + 1);
11865         }'
11866 }
11867
11868 test_102n() { # LU-4101 mdt: protect internal xattrs
11869         [ -z "$(which setfattr 2>/dev/null)" ] &&
11870                 skip "could not find setfattr"
11871         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11872         then
11873                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11874         fi
11875
11876         local file0=$DIR/$tfile.0
11877         local file1=$DIR/$tfile.1
11878         local xattr0=$TMP/$tfile.0
11879         local xattr1=$TMP/$tfile.1
11880         local namelist="lov lma lmv link fid version som hsm"
11881         local name
11882         local value
11883
11884         rm -rf $file0 $file1 $xattr0 $xattr1
11885         touch $file0 $file1
11886
11887         # Get 'before' xattrs of $file1.
11888         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11889
11890         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11891                 namelist+=" lfsck_namespace"
11892         for name in $namelist; do
11893                 # Try to copy xattr from $file0 to $file1.
11894                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11895
11896                 setfattr --name=trusted.$name --value="$value" $file1 ||
11897                         error "setxattr 'trusted.$name' failed"
11898
11899                 # Try to set a garbage xattr.
11900                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11901
11902                 if [[ x$name == "xlov" ]]; then
11903                         setfattr --name=trusted.lov --value="$value" $file1 &&
11904                         error "setxattr invalid 'trusted.lov' success"
11905                 else
11906                         setfattr --name=trusted.$name --value="$value" $file1 ||
11907                                 error "setxattr invalid 'trusted.$name' failed"
11908                 fi
11909
11910                 # Try to remove the xattr from $file1. We don't care if this
11911                 # appears to succeed or fail, we just don't want there to be
11912                 # any changes or crashes.
11913                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11914         done
11915
11916         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11917         then
11918                 name="lfsck_ns"
11919                 # Try to copy xattr from $file0 to $file1.
11920                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11921
11922                 setfattr --name=trusted.$name --value="$value" $file1 ||
11923                         error "setxattr 'trusted.$name' failed"
11924
11925                 # Try to set a garbage xattr.
11926                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11927
11928                 setfattr --name=trusted.$name --value="$value" $file1 ||
11929                         error "setxattr 'trusted.$name' failed"
11930
11931                 # Try to remove the xattr from $file1. We don't care if this
11932                 # appears to succeed or fail, we just don't want there to be
11933                 # any changes or crashes.
11934                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11935         fi
11936
11937         # Get 'after' xattrs of file1.
11938         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11939
11940         if ! diff $xattr0 $xattr1; then
11941                 error "before and after xattrs of '$file1' differ"
11942         fi
11943
11944         rm -rf $file0 $file1 $xattr0 $xattr1
11945
11946         return 0
11947 }
11948 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11949
11950 test_102p() { # LU-4703 setxattr did not check ownership
11951         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11952                 skip "MDS needs to be at least 2.5.56"
11953
11954         local testfile=$DIR/$tfile
11955
11956         touch $testfile
11957
11958         echo "setfacl as user..."
11959         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11960         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11961
11962         echo "setfattr as user..."
11963         setfacl -m "u:$RUNAS_ID:---" $testfile
11964         $RUNAS setfattr -x system.posix_acl_access $testfile
11965         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11966 }
11967 run_test 102p "check setxattr(2) correctly fails without permission"
11968
11969 test_102q() {
11970         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11971                 skip "MDS needs to be at least 2.6.92"
11972
11973         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11974 }
11975 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11976
11977 test_102r() {
11978         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11979                 skip "MDS needs to be at least 2.6.93"
11980
11981         touch $DIR/$tfile || error "touch"
11982         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11983         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11984         rm $DIR/$tfile || error "rm"
11985
11986         #normal directory
11987         mkdir -p $DIR/$tdir || error "mkdir"
11988         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11989         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11990         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11991                 error "$testfile error deleting user.author1"
11992         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11993                 grep "user.$(basename $tdir)" &&
11994                 error "$tdir did not delete user.$(basename $tdir)"
11995         rmdir $DIR/$tdir || error "rmdir"
11996
11997         #striped directory
11998         test_mkdir $DIR/$tdir
11999         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12000         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12001         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12002                 error "$testfile error deleting user.author1"
12003         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12004                 grep "user.$(basename $tdir)" &&
12005                 error "$tdir did not delete user.$(basename $tdir)"
12006         rmdir $DIR/$tdir || error "rm striped dir"
12007 }
12008 run_test 102r "set EAs with empty values"
12009
12010 test_102s() {
12011         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12012                 skip "MDS needs to be at least 2.11.52"
12013
12014         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12015
12016         save_lustre_params client "llite.*.xattr_cache" > $save
12017
12018         for cache in 0 1; do
12019                 lctl set_param llite.*.xattr_cache=$cache
12020
12021                 rm -f $DIR/$tfile
12022                 touch $DIR/$tfile || error "touch"
12023                 for prefix in lustre security system trusted user; do
12024                         # Note getxattr() may fail with 'Operation not
12025                         # supported' or 'No such attribute' depending
12026                         # on prefix and cache.
12027                         getfattr -n $prefix.n102s $DIR/$tfile &&
12028                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12029                 done
12030         done
12031
12032         restore_lustre_params < $save
12033 }
12034 run_test 102s "getting nonexistent xattrs should fail"
12035
12036 test_102t() {
12037         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12038                 skip "MDS needs to be at least 2.11.52"
12039
12040         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12041
12042         save_lustre_params client "llite.*.xattr_cache" > $save
12043
12044         for cache in 0 1; do
12045                 lctl set_param llite.*.xattr_cache=$cache
12046
12047                 for buf_size in 0 256; do
12048                         rm -f $DIR/$tfile
12049                         touch $DIR/$tfile || error "touch"
12050                         setfattr -n user.multiop $DIR/$tfile
12051                         $MULTIOP $DIR/$tfile oa$buf_size ||
12052                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12053                 done
12054         done
12055
12056         restore_lustre_params < $save
12057 }
12058 run_test 102t "zero length xattr values handled correctly"
12059
12060 run_acl_subtest()
12061 {
12062         local test=$LUSTRE/tests/acl/$1.test
12063         local tmp=$(mktemp -t $1-XXXXXX).test
12064         local bin=$2
12065         local dmn=$3
12066         local grp=$4
12067         local nbd=$5
12068         export LANG=C
12069
12070
12071         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12072         local sedgroups="-e s/:users/:$grp/g"
12073         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12074
12075         sed $sedusers $sedgroups < $test > $tmp
12076         stack_trap "rm -f $tmp"
12077         [[ -s $tmp ]] || error "sed failed to create test script"
12078
12079         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12080         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12081 }
12082
12083 test_103a() {
12084         [ "$UID" != 0 ] && skip "must run as root"
12085         $GSS && skip_env "could not run under gss"
12086         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12087                 skip_env "must have acl enabled"
12088         which setfacl || skip_env "could not find setfacl"
12089         remote_mds_nodsh && skip "remote MDS with nodsh"
12090
12091         ACLBIN=${ACLBIN:-"bin"}
12092         ACLDMN=${ACLDMN:-"daemon"}
12093         ACLGRP=${ACLGRP:-"users"}
12094         ACLNBD=${ACLNBD:-"nobody"}
12095
12096         if ! id $ACLBIN ||
12097            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12098                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12099                 ACLBIN=$USER0
12100                 if ! id $ACLBIN ; then
12101                         cat /etc/passwd
12102                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12103                 fi
12104         fi
12105         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12106            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12107                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12108                 ACLDMN=$USER1
12109                 if ! id $ACLDMN ; then
12110                         cat /etc/passwd
12111                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12112                 fi
12113         fi
12114         if ! getent group $ACLGRP; then
12115                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12116                 ACLGRP="$TSTUSR"
12117                 if ! getent group $ACLGRP; then
12118                         echo "cannot find group '$ACLGRP', adding it"
12119                         cat /etc/group
12120                         add_group 60000 $ACLGRP
12121                 fi
12122         fi
12123
12124         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12125         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12126         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12127
12128         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12129                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12130                 ACLGRP="$TSTUSR"
12131                 if ! getent group $ACLGRP; then
12132                         echo "cannot find group '$ACLGRP', adding it"
12133                         cat /etc/group
12134                         add_group 60000 $ACLGRP
12135                 fi
12136                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12137                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12138                         cat /etc/group
12139                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12140                 fi
12141         fi
12142
12143         gpasswd -a $ACLDMN $ACLBIN ||
12144                 error "setting client group failed"             # LU-5641
12145         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12146                 error "setting MDS group failed"                # LU-5641
12147
12148         declare -a identity_old
12149
12150         for num in $(seq $MDSCOUNT); do
12151                 switch_identity $num true || identity_old[$num]=$?
12152         done
12153
12154         SAVE_UMASK=$(umask)
12155         umask 0022
12156         mkdir -p $DIR/$tdir
12157         cd $DIR/$tdir
12158
12159         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12160         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12161         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12162         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12163         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12164         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12165         if ! id -u $ACLNBD ||
12166            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12167                 ACLNBD="nfsnobody"
12168                 if ! id -u $ACLNBD; then
12169                         ACLNBD=""
12170                 fi
12171         fi
12172         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12173                 add_group $(id -u $ACLNBD) $ACLNBD
12174                 if ! getent group $ACLNBD; then
12175                         ACLNBD=""
12176                 fi
12177         fi
12178         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12179            [[ -n "$ACLNBD" ]] && which setfattr; then
12180                 run_acl_subtest permissions_xattr \
12181                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12182         elif [[ -z "$ACLNBD" ]]; then
12183                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12184         else
12185                 echo "skip 'permission_xattr' test - missing setfattr command"
12186         fi
12187         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12188
12189         # inheritance test got from HP
12190         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12191         chmod +x make-tree || error "chmod +x failed"
12192         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12193         rm -f make-tree
12194
12195         echo "LU-974 ignore umask when acl is enabled..."
12196         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12197         if [ $MDSCOUNT -ge 2 ]; then
12198                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12199         fi
12200
12201         echo "LU-2561 newly created file is same size as directory..."
12202         if [ "$mds1_FSTYPE" != "zfs" ]; then
12203                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12204         else
12205                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12206         fi
12207
12208         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12209
12210         cd $SAVE_PWD
12211         umask $SAVE_UMASK
12212
12213         for num in $(seq $MDSCOUNT); do
12214                 if [ "${identity_old[$num]}" = 1 ]; then
12215                         switch_identity $num false || identity_old[$num]=$?
12216                 fi
12217         done
12218 }
12219 run_test 103a "acl test"
12220
12221 test_103b() {
12222         declare -a pids
12223         local U
12224
12225         for U in {0..511}; do
12226                 {
12227                 local O=$(printf "%04o" $U)
12228
12229                 umask $(printf "%04o" $((511 ^ $O)))
12230                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12231                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12232
12233                 (( $S == ($O & 0666) )) ||
12234                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12235
12236                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12237                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12238                 (( $S == ($O & 0666) )) ||
12239                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12240
12241                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12242                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12243                 (( $S == ($O & 0666) )) ||
12244                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12245                 rm -f $DIR/$tfile.[smp]$0
12246                 } &
12247                 local pid=$!
12248
12249                 # limit the concurrently running threads to 64. LU-11878
12250                 local idx=$((U % 64))
12251                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12252                 pids[idx]=$pid
12253         done
12254         wait
12255 }
12256 run_test 103b "umask lfs setstripe"
12257
12258 test_103c() {
12259         mkdir -p $DIR/$tdir
12260         cp -rp $DIR/$tdir $DIR/$tdir.bak
12261
12262         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12263                 error "$DIR/$tdir shouldn't contain default ACL"
12264         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12265                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12266         true
12267 }
12268 run_test 103c "'cp -rp' won't set empty acl"
12269
12270 test_103e() {
12271         local numacl
12272         local fileacl
12273         local saved_debug=$($LCTL get_param -n debug)
12274
12275         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12276                 skip "MDS needs to be at least 2.14.52"
12277
12278         large_xattr_enabled || skip_env "ea_inode feature disabled"
12279
12280         mkdir -p $DIR/$tdir
12281         # add big LOV EA to cause reply buffer overflow earlier
12282         $LFS setstripe -C 1000 $DIR/$tdir
12283         lctl set_param mdc.*-mdc*.stats=clear
12284
12285         $LCTL set_param debug=0
12286         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12287         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12288
12289         # add a large number of default ACLs (expect 8000+ for 2.13+)
12290         for U in {2..7000}; do
12291                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12292                         error "Able to add just $U default ACLs"
12293         done
12294         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12295         echo "$numacl default ACLs created"
12296
12297         stat $DIR/$tdir || error "Cannot stat directory"
12298         # check file creation
12299         touch $DIR/$tdir/$tfile ||
12300                 error "failed to create $tfile with $numacl default ACLs"
12301         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12302         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12303         echo "$fileacl ACLs were inherited"
12304         (( $fileacl == $numacl )) ||
12305                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12306         # check that new ACLs creation adds new ACLs to inherited ACLs
12307         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12308                 error "Cannot set new ACL"
12309         numacl=$((numacl + 1))
12310         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12311         (( $fileacl == $numacl )) ||
12312                 error "failed to add new ACL: $fileacl != $numacl as expected"
12313         # adds more ACLs to a file to reach their maximum at 8000+
12314         numacl=0
12315         for U in {20000..25000}; do
12316                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12317                 numacl=$((numacl + 1))
12318         done
12319         echo "Added $numacl more ACLs to the file"
12320         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12321         echo "Total $fileacl ACLs in file"
12322         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12323         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12324         rmdir $DIR/$tdir || error "Cannot remove directory"
12325 }
12326 run_test 103e "inheritance of big amount of default ACLs"
12327
12328 test_103f() {
12329         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12330                 skip "MDS needs to be at least 2.14.51"
12331
12332         large_xattr_enabled || skip_env "ea_inode feature disabled"
12333
12334         # enable changelog to consume more internal MDD buffers
12335         changelog_register
12336
12337         mkdir -p $DIR/$tdir
12338         # add big LOV EA
12339         $LFS setstripe -C 1000 $DIR/$tdir
12340         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12341         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12342         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12343         rmdir $DIR/$tdir || error "Cannot remove directory"
12344 }
12345 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12346
12347 test_104a() {
12348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12349
12350         touch $DIR/$tfile
12351         lfs df || error "lfs df failed"
12352         lfs df -ih || error "lfs df -ih failed"
12353         lfs df -h $DIR || error "lfs df -h $DIR failed"
12354         lfs df -i $DIR || error "lfs df -i $DIR failed"
12355         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12356         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12357
12358         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12359         lctl --device %$OSC deactivate
12360         lfs df || error "lfs df with deactivated OSC failed"
12361         lctl --device %$OSC activate
12362         # wait the osc back to normal
12363         wait_osc_import_ready client ost
12364
12365         lfs df || error "lfs df with reactivated OSC failed"
12366         rm -f $DIR/$tfile
12367 }
12368 run_test 104a "lfs df [-ih] [path] test ========================="
12369
12370 test_104b() {
12371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12372         [ $RUNAS_ID -eq $UID ] &&
12373                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12374
12375         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12376                         grep "Permission denied" | wc -l)))
12377         if [ $denied_cnt -ne 0 ]; then
12378                 error "lfs check servers test failed"
12379         fi
12380 }
12381 run_test 104b "$RUNAS lfs check servers test ===================="
12382
12383 #
12384 # Verify $1 is within range of $2.
12385 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12386 # $1 is <= 2% of $2. Else Fail.
12387 #
12388 value_in_range() {
12389         # Strip all units (M, G, T)
12390         actual=$(echo $1 | tr -d A-Z)
12391         expect=$(echo $2 | tr -d A-Z)
12392
12393         expect_lo=$(($expect * 98 / 100)) # 2% below
12394         expect_hi=$(($expect * 102 / 100)) # 2% above
12395
12396         # permit 2% drift above and below
12397         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12398 }
12399
12400 test_104c() {
12401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12402         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12403
12404         local ost_param="osd-zfs.$FSNAME-OST0000."
12405         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12406         local ofacets=$(get_facets OST)
12407         local mfacets=$(get_facets MDS)
12408         local saved_ost_blocks=
12409         local saved_mdt_blocks=
12410
12411         echo "Before recordsize change"
12412         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12413         df=($(df -h | grep "$MOUNT"$))
12414
12415         # For checking.
12416         echo "lfs output : ${lfs_df[*]}"
12417         echo "df  output : ${df[*]}"
12418
12419         for facet in ${ofacets//,/ }; do
12420                 if [ -z $saved_ost_blocks ]; then
12421                         saved_ost_blocks=$(do_facet $facet \
12422                                 lctl get_param -n $ost_param.blocksize)
12423                         echo "OST Blocksize: $saved_ost_blocks"
12424                 fi
12425                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12426                 do_facet $facet zfs set recordsize=32768 $ost
12427         done
12428
12429         # BS too small. Sufficient for functional testing.
12430         for facet in ${mfacets//,/ }; do
12431                 if [ -z $saved_mdt_blocks ]; then
12432                         saved_mdt_blocks=$(do_facet $facet \
12433                                 lctl get_param -n $mdt_param.blocksize)
12434                         echo "MDT Blocksize: $saved_mdt_blocks"
12435                 fi
12436                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12437                 do_facet $facet zfs set recordsize=32768 $mdt
12438         done
12439
12440         # Give new values chance to reflect change
12441         sleep 2
12442
12443         echo "After recordsize change"
12444         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12445         df_after=($(df -h | grep "$MOUNT"$))
12446
12447         # For checking.
12448         echo "lfs output : ${lfs_df_after[*]}"
12449         echo "df  output : ${df_after[*]}"
12450
12451         # Verify lfs df
12452         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12453                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12454         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12455                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12456         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12457                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12458
12459         # Verify df
12460         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12461                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12462         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12463                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12464         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12465                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12466
12467         # Restore MDT recordize back to original
12468         for facet in ${mfacets//,/ }; do
12469                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12470                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12471         done
12472
12473         # Restore OST recordize back to original
12474         for facet in ${ofacets//,/ }; do
12475                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12476                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12477         done
12478
12479         return 0
12480 }
12481 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12482
12483 test_104d() {
12484         (( $RUNAS_ID != $UID )) ||
12485                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12486
12487         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12488                 skip "lustre version doesn't support lctl dl with non-root"
12489
12490         # debugfs only allows root users to access files, so the
12491         # previous move of the "devices" file to debugfs broke
12492         # "lctl dl" for non-root users. The LU-9680 Netlink
12493         # interface again allows non-root users to list devices.
12494         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12495                 error "lctl dl doesn't work for non root"
12496
12497         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12498         [ "$ost_count" -eq $OSTCOUNT ]  ||
12499                 error "lctl dl reports wrong number of OST devices"
12500
12501         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12502         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12503                 error "lctl dl reports wrong number of MDT devices"
12504 }
12505 run_test 104d "$RUNAS lctl dl test"
12506
12507 test_105a() {
12508         # doesn't work on 2.4 kernels
12509         touch $DIR/$tfile
12510         if $(flock_is_enabled); then
12511                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12512         else
12513                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12514         fi
12515         rm -f $DIR/$tfile
12516 }
12517 run_test 105a "flock when mounted without -o flock test ========"
12518
12519 test_105b() {
12520         touch $DIR/$tfile
12521         if $(flock_is_enabled); then
12522                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12523         else
12524                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12525         fi
12526         rm -f $DIR/$tfile
12527 }
12528 run_test 105b "fcntl when mounted without -o flock test ========"
12529
12530 test_105c() {
12531         touch $DIR/$tfile
12532         if $(flock_is_enabled); then
12533                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12534         else
12535                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12536         fi
12537         rm -f $DIR/$tfile
12538 }
12539 run_test 105c "lockf when mounted without -o flock test"
12540
12541 test_105d() { # bug 15924
12542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12543
12544         test_mkdir $DIR/$tdir
12545         flock_is_enabled || skip_env "mount w/o flock enabled"
12546         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12547         $LCTL set_param fail_loc=0x80000315
12548         flocks_test 2 $DIR/$tdir
12549 }
12550 run_test 105d "flock race (should not freeze) ========"
12551
12552 test_105e() { # bug 22660 && 22040
12553         flock_is_enabled || skip_env "mount w/o flock enabled"
12554
12555         touch $DIR/$tfile
12556         flocks_test 3 $DIR/$tfile
12557 }
12558 run_test 105e "Two conflicting flocks from same process"
12559
12560 test_106() { #bug 10921
12561         test_mkdir $DIR/$tdir
12562         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12563         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12564 }
12565 run_test 106 "attempt exec of dir followed by chown of that dir"
12566
12567 test_107() {
12568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12569
12570         CDIR=`pwd`
12571         local file=core
12572
12573         cd $DIR
12574         rm -f $file
12575
12576         local save_pattern=$(sysctl -n kernel.core_pattern)
12577         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12578         sysctl -w kernel.core_pattern=$file
12579         sysctl -w kernel.core_uses_pid=0
12580
12581         ulimit -c unlimited
12582         sleep 60 &
12583         SLEEPPID=$!
12584
12585         sleep 1
12586
12587         kill -s 11 $SLEEPPID
12588         wait $SLEEPPID
12589         if [ -e $file ]; then
12590                 size=`stat -c%s $file`
12591                 [ $size -eq 0 ] && error "Fail to create core file $file"
12592         else
12593                 error "Fail to create core file $file"
12594         fi
12595         rm -f $file
12596         sysctl -w kernel.core_pattern=$save_pattern
12597         sysctl -w kernel.core_uses_pid=$save_uses_pid
12598         cd $CDIR
12599 }
12600 run_test 107 "Coredump on SIG"
12601
12602 test_110() {
12603         test_mkdir $DIR/$tdir
12604         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12605         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12606                 error "mkdir with 256 char should fail, but did not"
12607         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12608                 error "create with 255 char failed"
12609         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12610                 error "create with 256 char should fail, but did not"
12611
12612         ls -l $DIR/$tdir
12613         rm -rf $DIR/$tdir
12614 }
12615 run_test 110 "filename length checking"
12616
12617 test_116a() { # was previously test_116()
12618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12619         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12620         remote_mds_nodsh && skip "remote MDS with nodsh"
12621
12622         echo -n "Free space priority "
12623         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12624                 head -n1
12625         declare -a AVAIL
12626         free_min_max
12627
12628         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12629         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12630         stack_trap simple_cleanup_common
12631
12632         # Check if we need to generate uneven OSTs
12633         test_mkdir -p $DIR/$tdir/OST${MINI}
12634         local FILL=$((MINV / 4))
12635         local DIFF=$((MAXV - MINV))
12636         local DIFF2=$((DIFF * 100 / MINV))
12637
12638         local threshold=$(do_facet $SINGLEMDS \
12639                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12640         threshold=${threshold%%%}
12641         echo -n "Check for uneven OSTs: "
12642         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12643
12644         if [[ $DIFF2 -gt $threshold ]]; then
12645                 echo "ok"
12646                 echo "Don't need to fill OST$MINI"
12647         else
12648                 # generate uneven OSTs. Write 2% over the QOS threshold value
12649                 echo "no"
12650                 DIFF=$((threshold - DIFF2 + 2))
12651                 DIFF2=$((MINV * DIFF / 100))
12652                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12653                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12654                         error "setstripe failed"
12655                 DIFF=$((DIFF2 / 2048))
12656                 i=0
12657                 while [ $i -lt $DIFF ]; do
12658                         i=$((i + 1))
12659                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12660                                 bs=2M count=1 2>/dev/null
12661                         echo -n .
12662                 done
12663                 echo .
12664                 sync
12665                 sleep_maxage
12666                 free_min_max
12667         fi
12668
12669         DIFF=$((MAXV - MINV))
12670         DIFF2=$((DIFF * 100 / MINV))
12671         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12672         if [ $DIFF2 -gt $threshold ]; then
12673                 echo "ok"
12674         else
12675                 skip "QOS imbalance criteria not met"
12676         fi
12677
12678         MINI1=$MINI
12679         MINV1=$MINV
12680         MAXI1=$MAXI
12681         MAXV1=$MAXV
12682
12683         # now fill using QOS
12684         $LFS setstripe -c 1 $DIR/$tdir
12685         FILL=$((FILL / 200))
12686         if [ $FILL -gt 600 ]; then
12687                 FILL=600
12688         fi
12689         echo "writing $FILL files to QOS-assigned OSTs"
12690         i=0
12691         while [ $i -lt $FILL ]; do
12692                 i=$((i + 1))
12693                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12694                         count=1 2>/dev/null
12695                 echo -n .
12696         done
12697         echo "wrote $i 200k files"
12698         sync
12699         sleep_maxage
12700
12701         echo "Note: free space may not be updated, so measurements might be off"
12702         free_min_max
12703         DIFF2=$((MAXV - MINV))
12704         echo "free space delta: orig $DIFF final $DIFF2"
12705         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12706         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12707         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12708         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12709         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12710         if [[ $DIFF -gt 0 ]]; then
12711                 FILL=$((DIFF2 * 100 / DIFF - 100))
12712                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12713         fi
12714
12715         # Figure out which files were written where
12716         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12717                awk '/'$MINI1': / {print $2; exit}')
12718         echo $UUID
12719         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12720         echo "$MINC files created on smaller OST $MINI1"
12721         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12722                awk '/'$MAXI1': / {print $2; exit}')
12723         echo $UUID
12724         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12725         echo "$MAXC files created on larger OST $MAXI1"
12726         if [[ $MINC -gt 0 ]]; then
12727                 FILL=$((MAXC * 100 / MINC - 100))
12728                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12729         fi
12730         [[ $MAXC -gt $MINC ]] ||
12731                 error_ignore LU-9 "stripe QOS didn't balance free space"
12732 }
12733 run_test 116a "stripe QOS: free space balance ==================="
12734
12735 test_116b() { # LU-2093
12736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12737         remote_mds_nodsh && skip "remote MDS with nodsh"
12738
12739 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12740         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12741                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12742         [ -z "$old_rr" ] && skip "no QOS"
12743         do_facet $SINGLEMDS lctl set_param \
12744                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12745         mkdir -p $DIR/$tdir
12746         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12747         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12748         do_facet $SINGLEMDS lctl set_param fail_loc=0
12749         rm -rf $DIR/$tdir
12750         do_facet $SINGLEMDS lctl set_param \
12751                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12752 }
12753 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12754
12755 test_117() # bug 10891
12756 {
12757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12758
12759         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12760         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12761         lctl set_param fail_loc=0x21e
12762         > $DIR/$tfile || error "truncate failed"
12763         lctl set_param fail_loc=0
12764         echo "Truncate succeeded."
12765         rm -f $DIR/$tfile
12766 }
12767 run_test 117 "verify osd extend =========="
12768
12769 NO_SLOW_RESENDCOUNT=4
12770 export OLD_RESENDCOUNT=""
12771 set_resend_count () {
12772         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12773         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12774         lctl set_param -n $PROC_RESENDCOUNT $1
12775         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12776 }
12777
12778 # for reduce test_118* time (b=14842)
12779 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12780
12781 # Reset async IO behavior after error case
12782 reset_async() {
12783         FILE=$DIR/reset_async
12784
12785         # Ensure all OSCs are cleared
12786         $LFS setstripe -c -1 $FILE
12787         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12788         sync
12789         rm $FILE
12790 }
12791
12792 test_118a() #bug 11710
12793 {
12794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12795
12796         reset_async
12797
12798         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12799         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12800         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12801
12802         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12803                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12804                 return 1;
12805         fi
12806         rm -f $DIR/$tfile
12807 }
12808 run_test 118a "verify O_SYNC works =========="
12809
12810 test_118b()
12811 {
12812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12813         remote_ost_nodsh && skip "remote OST with nodsh"
12814
12815         reset_async
12816
12817         #define OBD_FAIL_SRV_ENOENT 0x217
12818         set_nodes_failloc "$(osts_nodes)" 0x217
12819         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12820         RC=$?
12821         set_nodes_failloc "$(osts_nodes)" 0
12822         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12823         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12824                     grep -c writeback)
12825
12826         if [[ $RC -eq 0 ]]; then
12827                 error "Must return error due to dropped pages, rc=$RC"
12828                 return 1;
12829         fi
12830
12831         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12832                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12833                 return 1;
12834         fi
12835
12836         echo "Dirty pages not leaked on ENOENT"
12837
12838         # Due to the above error the OSC will issue all RPCs syncronously
12839         # until a subsequent RPC completes successfully without error.
12840         $MULTIOP $DIR/$tfile Ow4096yc
12841         rm -f $DIR/$tfile
12842
12843         return 0
12844 }
12845 run_test 118b "Reclaim dirty pages on fatal error =========="
12846
12847 test_118c()
12848 {
12849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12850
12851         # for 118c, restore the original resend count, LU-1940
12852         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12853                                 set_resend_count $OLD_RESENDCOUNT
12854         remote_ost_nodsh && skip "remote OST with nodsh"
12855
12856         reset_async
12857
12858         #define OBD_FAIL_OST_EROFS               0x216
12859         set_nodes_failloc "$(osts_nodes)" 0x216
12860
12861         # multiop should block due to fsync until pages are written
12862         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12863         MULTIPID=$!
12864         sleep 1
12865
12866         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12867                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12868         fi
12869
12870         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12871                     grep -c writeback)
12872         if [[ $WRITEBACK -eq 0 ]]; then
12873                 error "No page in writeback, writeback=$WRITEBACK"
12874         fi
12875
12876         set_nodes_failloc "$(osts_nodes)" 0
12877         wait $MULTIPID
12878         RC=$?
12879         if [[ $RC -ne 0 ]]; then
12880                 error "Multiop fsync failed, rc=$RC"
12881         fi
12882
12883         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12884         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12885                     grep -c writeback)
12886         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12887                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12888         fi
12889
12890         rm -f $DIR/$tfile
12891         echo "Dirty pages flushed via fsync on EROFS"
12892         return 0
12893 }
12894 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12895
12896 # continue to use small resend count to reduce test_118* time (b=14842)
12897 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12898
12899 test_118d()
12900 {
12901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12902         remote_ost_nodsh && skip "remote OST with nodsh"
12903
12904         reset_async
12905
12906         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12907         set_nodes_failloc "$(osts_nodes)" 0x214
12908         # multiop should block due to fsync until pages are written
12909         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12910         MULTIPID=$!
12911         sleep 1
12912
12913         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12914                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12915         fi
12916
12917         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12918                     grep -c writeback)
12919         if [[ $WRITEBACK -eq 0 ]]; then
12920                 error "No page in writeback, writeback=$WRITEBACK"
12921         fi
12922
12923         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12924         set_nodes_failloc "$(osts_nodes)" 0
12925
12926         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12927         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12928                     grep -c writeback)
12929         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12930                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12931         fi
12932
12933         rm -f $DIR/$tfile
12934         echo "Dirty pages gaurenteed flushed via fsync"
12935         return 0
12936 }
12937 run_test 118d "Fsync validation inject a delay of the bulk =========="
12938
12939 test_118f() {
12940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12941
12942         reset_async
12943
12944         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12945         lctl set_param fail_loc=0x8000040a
12946
12947         # Should simulate EINVAL error which is fatal
12948         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12949         RC=$?
12950         if [[ $RC -eq 0 ]]; then
12951                 error "Must return error due to dropped pages, rc=$RC"
12952         fi
12953
12954         lctl set_param fail_loc=0x0
12955
12956         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12957         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12958         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12959                     grep -c writeback)
12960         if [[ $LOCKED -ne 0 ]]; then
12961                 error "Locked pages remain in cache, locked=$LOCKED"
12962         fi
12963
12964         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12965                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12966         fi
12967
12968         rm -f $DIR/$tfile
12969         echo "No pages locked after fsync"
12970
12971         reset_async
12972         return 0
12973 }
12974 run_test 118f "Simulate unrecoverable OSC side error =========="
12975
12976 test_118g() {
12977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12978
12979         reset_async
12980
12981         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12982         lctl set_param fail_loc=0x406
12983
12984         # simulate local -ENOMEM
12985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12986         RC=$?
12987
12988         lctl set_param fail_loc=0
12989         if [[ $RC -eq 0 ]]; then
12990                 error "Must return error due to dropped pages, rc=$RC"
12991         fi
12992
12993         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12994         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12995         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12996                         grep -c writeback)
12997         if [[ $LOCKED -ne 0 ]]; then
12998                 error "Locked pages remain in cache, locked=$LOCKED"
12999         fi
13000
13001         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13002                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13003         fi
13004
13005         rm -f $DIR/$tfile
13006         echo "No pages locked after fsync"
13007
13008         reset_async
13009         return 0
13010 }
13011 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13012
13013 test_118h() {
13014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13015         remote_ost_nodsh && skip "remote OST with nodsh"
13016
13017         reset_async
13018
13019         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13020         set_nodes_failloc "$(osts_nodes)" 0x20e
13021         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13022         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13023         RC=$?
13024
13025         set_nodes_failloc "$(osts_nodes)" 0
13026         if [[ $RC -eq 0 ]]; then
13027                 error "Must return error due to dropped pages, rc=$RC"
13028         fi
13029
13030         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13031         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13032         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13033                     grep -c writeback)
13034         if [[ $LOCKED -ne 0 ]]; then
13035                 error "Locked pages remain in cache, locked=$LOCKED"
13036         fi
13037
13038         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13039                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13040         fi
13041
13042         rm -f $DIR/$tfile
13043         echo "No pages locked after fsync"
13044
13045         return 0
13046 }
13047 run_test 118h "Verify timeout in handling recoverables errors  =========="
13048
13049 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13050
13051 test_118i() {
13052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13053         remote_ost_nodsh && skip "remote OST with nodsh"
13054
13055         reset_async
13056
13057         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13058         set_nodes_failloc "$(osts_nodes)" 0x20e
13059
13060         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13061         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13062         PID=$!
13063         sleep 5
13064         set_nodes_failloc "$(osts_nodes)" 0
13065
13066         wait $PID
13067         RC=$?
13068         if [[ $RC -ne 0 ]]; then
13069                 error "got error, but should be not, rc=$RC"
13070         fi
13071
13072         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13073         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13074         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13075         if [[ $LOCKED -ne 0 ]]; then
13076                 error "Locked pages remain in cache, locked=$LOCKED"
13077         fi
13078
13079         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13080                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13081         fi
13082
13083         rm -f $DIR/$tfile
13084         echo "No pages locked after fsync"
13085
13086         return 0
13087 }
13088 run_test 118i "Fix error before timeout in recoverable error  =========="
13089
13090 [ "$SLOW" = "no" ] && set_resend_count 4
13091
13092 test_118j() {
13093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13094         remote_ost_nodsh && skip "remote OST with nodsh"
13095
13096         reset_async
13097
13098         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13099         set_nodes_failloc "$(osts_nodes)" 0x220
13100
13101         # return -EIO from OST
13102         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13103         RC=$?
13104         set_nodes_failloc "$(osts_nodes)" 0x0
13105         if [[ $RC -eq 0 ]]; then
13106                 error "Must return error due to dropped pages, rc=$RC"
13107         fi
13108
13109         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13110         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13111         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13112         if [[ $LOCKED -ne 0 ]]; then
13113                 error "Locked pages remain in cache, locked=$LOCKED"
13114         fi
13115
13116         # in recoverable error on OST we want resend and stay until it finished
13117         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13118                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13119         fi
13120
13121         rm -f $DIR/$tfile
13122         echo "No pages locked after fsync"
13123
13124         return 0
13125 }
13126 run_test 118j "Simulate unrecoverable OST side error =========="
13127
13128 test_118k()
13129 {
13130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13131         remote_ost_nodsh && skip "remote OSTs with nodsh"
13132
13133         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13134         set_nodes_failloc "$(osts_nodes)" 0x20e
13135         test_mkdir $DIR/$tdir
13136
13137         for ((i=0;i<10;i++)); do
13138                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13139                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13140                 SLEEPPID=$!
13141                 sleep 0.500s
13142                 kill $SLEEPPID
13143                 wait $SLEEPPID
13144         done
13145
13146         set_nodes_failloc "$(osts_nodes)" 0
13147         rm -rf $DIR/$tdir
13148 }
13149 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13150
13151 test_118l() # LU-646
13152 {
13153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13154
13155         test_mkdir $DIR/$tdir
13156         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13157         rm -rf $DIR/$tdir
13158 }
13159 run_test 118l "fsync dir"
13160
13161 test_118m() # LU-3066
13162 {
13163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13164
13165         test_mkdir $DIR/$tdir
13166         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13167         rm -rf $DIR/$tdir
13168 }
13169 run_test 118m "fdatasync dir ========="
13170
13171 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13172
13173 test_118n()
13174 {
13175         local begin
13176         local end
13177
13178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13179         remote_ost_nodsh && skip "remote OSTs with nodsh"
13180
13181         # Sleep to avoid a cached response.
13182         #define OBD_STATFS_CACHE_SECONDS 1
13183         sleep 2
13184
13185         # Inject a 10 second delay in the OST_STATFS handler.
13186         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13187         set_nodes_failloc "$(osts_nodes)" 0x242
13188
13189         begin=$SECONDS
13190         stat --file-system $MOUNT > /dev/null
13191         end=$SECONDS
13192
13193         set_nodes_failloc "$(osts_nodes)" 0
13194
13195         if ((end - begin > 20)); then
13196             error "statfs took $((end - begin)) seconds, expected 10"
13197         fi
13198 }
13199 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13200
13201 test_119a() # bug 11737
13202 {
13203         BSIZE=$((512 * 1024))
13204         directio write $DIR/$tfile 0 1 $BSIZE
13205         # We ask to read two blocks, which is more than a file size.
13206         # directio will indicate an error when requested and actual
13207         # sizes aren't equeal (a normal situation in this case) and
13208         # print actual read amount.
13209         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13210         if [ "$NOB" != "$BSIZE" ]; then
13211                 error "read $NOB bytes instead of $BSIZE"
13212         fi
13213         rm -f $DIR/$tfile
13214 }
13215 run_test 119a "Short directIO read must return actual read amount"
13216
13217 test_119b() # bug 11737
13218 {
13219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13220
13221         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13222         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13223         sync
13224         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13225                 error "direct read failed"
13226         rm -f $DIR/$tfile
13227 }
13228 run_test 119b "Sparse directIO read must return actual read amount"
13229
13230 test_119c() # bug 13099
13231 {
13232         BSIZE=1048576
13233         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13234         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13235         rm -f $DIR/$tfile
13236 }
13237 run_test 119c "Testing for direct read hitting hole"
13238
13239 test_119d() # bug 15950
13240 {
13241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13242
13243         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13244         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13245         BSIZE=1048576
13246         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13247         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13248         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13249         lctl set_param fail_loc=0x40d
13250         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13251         pid_dio=$!
13252         sleep 1
13253         cat $DIR/$tfile > /dev/null &
13254         lctl set_param fail_loc=0
13255         pid_reads=$!
13256         wait $pid_dio
13257         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13258         sleep 2
13259         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13260         error "the read rpcs have not completed in 2s"
13261         rm -f $DIR/$tfile
13262         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13263 }
13264 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13265
13266 test_120a() {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268         remote_mds_nodsh && skip "remote MDS with nodsh"
13269         test_mkdir -i0 -c1 $DIR/$tdir
13270         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13271                 skip_env "no early lock cancel on server"
13272
13273         lru_resize_disable mdc
13274         lru_resize_disable osc
13275         cancel_lru_locks mdc
13276         # asynchronous object destroy at MDT could cause bl ast to client
13277         cancel_lru_locks osc
13278
13279         stat $DIR/$tdir > /dev/null
13280         can1=$(do_facet mds1 \
13281                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13282                awk '/ldlm_cancel/ {print $2}')
13283         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13284                awk '/ldlm_bl_callback/ {print $2}')
13285         test_mkdir -i0 -c1 $DIR/$tdir/d1
13286         can2=$(do_facet mds1 \
13287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13288                awk '/ldlm_cancel/ {print $2}')
13289         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13290                awk '/ldlm_bl_callback/ {print $2}')
13291         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13292         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13293         lru_resize_enable mdc
13294         lru_resize_enable osc
13295 }
13296 run_test 120a "Early Lock Cancel: mkdir test"
13297
13298 test_120b() {
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300         remote_mds_nodsh && skip "remote MDS with nodsh"
13301         test_mkdir $DIR/$tdir
13302         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13303                 skip_env "no early lock cancel on server"
13304
13305         lru_resize_disable mdc
13306         lru_resize_disable osc
13307         cancel_lru_locks mdc
13308         stat $DIR/$tdir > /dev/null
13309         can1=$(do_facet $SINGLEMDS \
13310                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13311                awk '/ldlm_cancel/ {print $2}')
13312         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13313                awk '/ldlm_bl_callback/ {print $2}')
13314         touch $DIR/$tdir/f1
13315         can2=$(do_facet $SINGLEMDS \
13316                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13317                awk '/ldlm_cancel/ {print $2}')
13318         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13319                awk '/ldlm_bl_callback/ {print $2}')
13320         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13321         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13322         lru_resize_enable mdc
13323         lru_resize_enable osc
13324 }
13325 run_test 120b "Early Lock Cancel: create test"
13326
13327 test_120c() {
13328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13329         remote_mds_nodsh && skip "remote MDS with nodsh"
13330         test_mkdir -i0 -c1 $DIR/$tdir
13331         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13332                 skip "no early lock cancel on server"
13333
13334         lru_resize_disable mdc
13335         lru_resize_disable osc
13336         test_mkdir -i0 -c1 $DIR/$tdir/d1
13337         test_mkdir -i0 -c1 $DIR/$tdir/d2
13338         touch $DIR/$tdir/d1/f1
13339         cancel_lru_locks mdc
13340         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13341         can1=$(do_facet mds1 \
13342                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13343                awk '/ldlm_cancel/ {print $2}')
13344         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13345                awk '/ldlm_bl_callback/ {print $2}')
13346         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13347         can2=$(do_facet mds1 \
13348                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13349                awk '/ldlm_cancel/ {print $2}')
13350         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13351                awk '/ldlm_bl_callback/ {print $2}')
13352         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13353         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13354         lru_resize_enable mdc
13355         lru_resize_enable osc
13356 }
13357 run_test 120c "Early Lock Cancel: link test"
13358
13359 test_120d() {
13360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13361         remote_mds_nodsh && skip "remote MDS with nodsh"
13362         test_mkdir -i0 -c1 $DIR/$tdir
13363         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13364                 skip_env "no early lock cancel on server"
13365
13366         lru_resize_disable mdc
13367         lru_resize_disable osc
13368         touch $DIR/$tdir
13369         cancel_lru_locks mdc
13370         stat $DIR/$tdir > /dev/null
13371         can1=$(do_facet mds1 \
13372                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13373                awk '/ldlm_cancel/ {print $2}')
13374         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13375                awk '/ldlm_bl_callback/ {print $2}')
13376         chmod a+x $DIR/$tdir
13377         can2=$(do_facet mds1 \
13378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13379                awk '/ldlm_cancel/ {print $2}')
13380         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13381                awk '/ldlm_bl_callback/ {print $2}')
13382         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13383         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13384         lru_resize_enable mdc
13385         lru_resize_enable osc
13386 }
13387 run_test 120d "Early Lock Cancel: setattr test"
13388
13389 test_120e() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13392                 skip_env "no early lock cancel on server"
13393         remote_mds_nodsh && skip "remote MDS with nodsh"
13394
13395         local dlmtrace_set=false
13396
13397         test_mkdir -i0 -c1 $DIR/$tdir
13398         lru_resize_disable mdc
13399         lru_resize_disable osc
13400         ! $LCTL get_param debug | grep -q dlmtrace &&
13401                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13402         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13403         cancel_lru_locks mdc
13404         cancel_lru_locks osc
13405         dd if=$DIR/$tdir/f1 of=/dev/null
13406         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13407         # XXX client can not do early lock cancel of OST lock
13408         # during unlink (LU-4206), so cancel osc lock now.
13409         sleep 2
13410         cancel_lru_locks osc
13411         can1=$(do_facet mds1 \
13412                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13413                awk '/ldlm_cancel/ {print $2}')
13414         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13415                awk '/ldlm_bl_callback/ {print $2}')
13416         unlink $DIR/$tdir/f1
13417         sleep 5
13418         can2=$(do_facet mds1 \
13419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13420                awk '/ldlm_cancel/ {print $2}')
13421         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13422                awk '/ldlm_bl_callback/ {print $2}')
13423         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13424                 $LCTL dk $TMP/cancel.debug.txt
13425         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13426                 $LCTL dk $TMP/blocking.debug.txt
13427         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13428         lru_resize_enable mdc
13429         lru_resize_enable osc
13430 }
13431 run_test 120e "Early Lock Cancel: unlink test"
13432
13433 test_120f() {
13434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13435         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13436                 skip_env "no early lock cancel on server"
13437         remote_mds_nodsh && skip "remote MDS with nodsh"
13438
13439         test_mkdir -i0 -c1 $DIR/$tdir
13440         lru_resize_disable mdc
13441         lru_resize_disable osc
13442         test_mkdir -i0 -c1 $DIR/$tdir/d1
13443         test_mkdir -i0 -c1 $DIR/$tdir/d2
13444         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13445         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13446         cancel_lru_locks mdc
13447         cancel_lru_locks osc
13448         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13449         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13450         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13451         # XXX client can not do early lock cancel of OST lock
13452         # during rename (LU-4206), so cancel osc lock now.
13453         sleep 2
13454         cancel_lru_locks osc
13455         can1=$(do_facet mds1 \
13456                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13457                awk '/ldlm_cancel/ {print $2}')
13458         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13459                awk '/ldlm_bl_callback/ {print $2}')
13460         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13461         sleep 5
13462         can2=$(do_facet mds1 \
13463                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13464                awk '/ldlm_cancel/ {print $2}')
13465         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13466                awk '/ldlm_bl_callback/ {print $2}')
13467         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13468         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13469         lru_resize_enable mdc
13470         lru_resize_enable osc
13471 }
13472 run_test 120f "Early Lock Cancel: rename test"
13473
13474 test_120g() {
13475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13476         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13477                 skip_env "no early lock cancel on server"
13478         remote_mds_nodsh && skip "remote MDS with nodsh"
13479
13480         lru_resize_disable mdc
13481         lru_resize_disable osc
13482         count=10000
13483         echo create $count files
13484         test_mkdir $DIR/$tdir
13485         cancel_lru_locks mdc
13486         cancel_lru_locks osc
13487         t0=$(date +%s)
13488
13489         can0=$(do_facet $SINGLEMDS \
13490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13491                awk '/ldlm_cancel/ {print $2}')
13492         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13493                awk '/ldlm_bl_callback/ {print $2}')
13494         createmany -o $DIR/$tdir/f $count
13495         sync
13496         can1=$(do_facet $SINGLEMDS \
13497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13498                awk '/ldlm_cancel/ {print $2}')
13499         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13500                awk '/ldlm_bl_callback/ {print $2}')
13501         t1=$(date +%s)
13502         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13503         echo rm $count files
13504         rm -r $DIR/$tdir
13505         sync
13506         can2=$(do_facet $SINGLEMDS \
13507                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13508                awk '/ldlm_cancel/ {print $2}')
13509         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13510                awk '/ldlm_bl_callback/ {print $2}')
13511         t2=$(date +%s)
13512         echo total: $count removes in $((t2-t1))
13513         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13514         sleep 2
13515         # wait for commitment of removal
13516         lru_resize_enable mdc
13517         lru_resize_enable osc
13518 }
13519 run_test 120g "Early Lock Cancel: performance test"
13520
13521 test_121() { #bug #10589
13522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13523
13524         rm -rf $DIR/$tfile
13525         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13526 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13527         lctl set_param fail_loc=0x310
13528         cancel_lru_locks osc > /dev/null
13529         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13530         lctl set_param fail_loc=0
13531         [[ $reads -eq $writes ]] ||
13532                 error "read $reads blocks, must be $writes blocks"
13533 }
13534 run_test 121 "read cancel race ========="
13535
13536 test_123a_base() { # was test 123, statahead(bug 11401)
13537         local lsx="$1"
13538
13539         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13540
13541         SLOWOK=0
13542         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13543                 log "testing UP system. Performance may be lower than expected."
13544                 SLOWOK=1
13545         fi
13546         running_in_vm && SLOWOK=1
13547
13548         rm -rf $DIR/$tdir
13549         test_mkdir $DIR/$tdir
13550         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13551         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13552         MULT=10
13553         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13554                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13555
13556                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13557                 lctl set_param -n llite.*.statahead_max 0
13558                 lctl get_param llite.*.statahead_max
13559                 cancel_lru_locks mdc
13560                 cancel_lru_locks osc
13561                 stime=$(date +%s)
13562                 time $lsx $DIR/$tdir | wc -l
13563                 etime=$(date +%s)
13564                 delta=$((etime - stime))
13565                 log "$lsx $i files without statahead: $delta sec"
13566                 lctl set_param llite.*.statahead_max=$max
13567
13568                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13569                          awk '/statahead.wrong:/ { print $NF }')
13570                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13571                 cancel_lru_locks mdc
13572                 cancel_lru_locks osc
13573                 stime=$(date +%s)
13574                 time $lsx $DIR/$tdir | wc -l
13575                 etime=$(date +%s)
13576                 delta_sa=$((etime - stime))
13577                 log "$lsx $i files with statahead: $delta_sa sec"
13578                 lctl get_param -n llite.*.statahead_stats
13579                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13580                          awk '/statahead.wrong:/ { print $NF }')
13581
13582                 [[ $swrong -lt $ewrong ]] &&
13583                         log "statahead was stopped, maybe too many locks held!"
13584                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13585
13586                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13587                         max=$(lctl get_param -n llite.*.statahead_max |
13588                                 head -n 1)
13589                         lctl set_param -n llite.*.statahead_max 0
13590                         lctl get_param llite.*.statahead_max
13591                         cancel_lru_locks mdc
13592                         cancel_lru_locks osc
13593                         stime=$(date +%s)
13594                         time $lsx $DIR/$tdir | wc -l
13595                         etime=$(date +%s)
13596                         delta=$((etime - stime))
13597                         log "$lsx $i files again without statahead: $delta sec"
13598                         lctl set_param llite.*.statahead_max=$max
13599                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13600                                 if [ $SLOWOK -eq 0 ]; then
13601                                         error "$lsx $i files is slower with statahead!"
13602                                 else
13603                                         log "$lsx $i files is slower with statahead!"
13604                                 fi
13605                                 break
13606                         fi
13607                 fi
13608
13609                 [ $delta -gt 20 ] && break
13610                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13611                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13612         done
13613         log "$lsx done"
13614
13615         stime=$(date +%s)
13616         rm -r $DIR/$tdir
13617         sync
13618         etime=$(date +%s)
13619         delta=$((etime - stime))
13620         log "rm -r $DIR/$tdir/: $delta seconds"
13621         log "rm done"
13622         lctl get_param -n llite.*.statahead_stats
13623 }
13624
13625 test_123aa() {
13626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13627
13628         test_123a_base "ls -l"
13629 }
13630 run_test 123aa "verify statahead work"
13631
13632 test_123ab() {
13633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13634
13635         statx_supported || skip_env "Test must be statx() syscall supported"
13636
13637         test_123a_base "$STATX -l"
13638 }
13639 run_test 123ab "verify statahead work by using statx"
13640
13641 test_123ac() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643
13644         statx_supported || skip_env "Test must be statx() syscall supported"
13645
13646         local rpcs_before
13647         local rpcs_after
13648         local agl_before
13649         local agl_after
13650
13651         cancel_lru_locks $OSC
13652         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13653         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13654                      awk '/agl.total:/ { print $NF }')
13655         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13656         test_123a_base "$STATX --cached=always -D"
13657         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13658                     awk '/agl.total:/ { print $NF }')
13659         [ $agl_before -eq $agl_after ] ||
13660                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13661         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13662         [ $rpcs_after -eq $rpcs_before ] ||
13663                 error "$STATX should not send glimpse RPCs to $OSC"
13664 }
13665 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13666
13667 test_123b () { # statahead(bug 15027)
13668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13669
13670         test_mkdir $DIR/$tdir
13671         createmany -o $DIR/$tdir/$tfile-%d 1000
13672
13673         cancel_lru_locks mdc
13674         cancel_lru_locks osc
13675
13676 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13677         lctl set_param fail_loc=0x80000803
13678         ls -lR $DIR/$tdir > /dev/null
13679         log "ls done"
13680         lctl set_param fail_loc=0x0
13681         lctl get_param -n llite.*.statahead_stats
13682         rm -r $DIR/$tdir
13683         sync
13684
13685 }
13686 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13687
13688 test_123c() {
13689         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13690
13691         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13692         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13693         touch $DIR/$tdir.1/{1..3}
13694         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13695
13696         remount_client $MOUNT
13697
13698         $MULTIOP $DIR/$tdir.0 Q
13699
13700         # let statahead to complete
13701         ls -l $DIR/$tdir.0 > /dev/null
13702
13703         testid=$(echo $TESTNAME | tr '_' ' ')
13704         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13705                 error "statahead warning" || true
13706 }
13707 run_test 123c "Can not initialize inode warning on DNE statahead"
13708
13709 test_123d() {
13710         local num=100
13711         local swrong
13712         local ewrong
13713
13714         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13715         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13716                 error "setdirstripe $DIR/$tdir failed"
13717         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13718         remount_client $MOUNT
13719         $LCTL get_param llite.*.statahead_max
13720         $LCTL set_param llite.*.statahead_stats=0 ||
13721                 error "clear statahead_stats failed"
13722         swrong=$(lctl get_param -n llite.*.statahead_stats |
13723                  awk '/statahead.wrong:/ { print $NF }')
13724         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13725         # wait for statahead thread finished to update hit/miss stats.
13726         sleep 1
13727         $LCTL get_param -n llite.*.statahead_stats
13728         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13729                  awk '/statahead.wrong:/ { print $NF }')
13730         (( $swrong == $ewrong )) ||
13731                 log "statahead was stopped, maybe too many locks held!"
13732 }
13733 run_test 123d "Statahead on striped directories works correctly"
13734
13735 test_124a() {
13736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13737         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13738                 skip_env "no lru resize on server"
13739
13740         local NR=2000
13741
13742         test_mkdir $DIR/$tdir
13743
13744         log "create $NR files at $DIR/$tdir"
13745         createmany -o $DIR/$tdir/f $NR ||
13746                 error "failed to create $NR files in $DIR/$tdir"
13747
13748         cancel_lru_locks mdc
13749         ls -l $DIR/$tdir > /dev/null
13750
13751         local NSDIR=""
13752         local LRU_SIZE=0
13753         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13754                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13755                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13756                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13757                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13758                         log "NSDIR=$NSDIR"
13759                         log "NS=$(basename $NSDIR)"
13760                         break
13761                 fi
13762         done
13763
13764         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13765                 skip "Not enough cached locks created!"
13766         fi
13767         log "LRU=$LRU_SIZE"
13768
13769         local SLEEP=30
13770
13771         # We know that lru resize allows one client to hold $LIMIT locks
13772         # for 10h. After that locks begin to be killed by client.
13773         local MAX_HRS=10
13774         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13775         log "LIMIT=$LIMIT"
13776         if [ $LIMIT -lt $LRU_SIZE ]; then
13777                 skip "Limit is too small $LIMIT"
13778         fi
13779
13780         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13781         # killing locks. Some time was spent for creating locks. This means
13782         # that up to the moment of sleep finish we must have killed some of
13783         # them (10-100 locks). This depends on how fast ther were created.
13784         # Many of them were touched in almost the same moment and thus will
13785         # be killed in groups.
13786         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13787
13788         # Use $LRU_SIZE_B here to take into account real number of locks
13789         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13790         local LRU_SIZE_B=$LRU_SIZE
13791         log "LVF=$LVF"
13792         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13793         log "OLD_LVF=$OLD_LVF"
13794         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13795
13796         # Let's make sure that we really have some margin. Client checks
13797         # cached locks every 10 sec.
13798         SLEEP=$((SLEEP+20))
13799         log "Sleep ${SLEEP} sec"
13800         local SEC=0
13801         while ((SEC<$SLEEP)); do
13802                 echo -n "..."
13803                 sleep 5
13804                 SEC=$((SEC+5))
13805                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13806                 echo -n "$LRU_SIZE"
13807         done
13808         echo ""
13809         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13810         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13811
13812         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13813                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13814                 unlinkmany $DIR/$tdir/f $NR
13815                 return
13816         }
13817
13818         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13819         log "unlink $NR files at $DIR/$tdir"
13820         unlinkmany $DIR/$tdir/f $NR
13821 }
13822 run_test 124a "lru resize ======================================="
13823
13824 get_max_pool_limit()
13825 {
13826         local limit=$($LCTL get_param \
13827                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13828         local max=0
13829         for l in $limit; do
13830                 if [[ $l -gt $max ]]; then
13831                         max=$l
13832                 fi
13833         done
13834         echo $max
13835 }
13836
13837 test_124b() {
13838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13839         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13840                 skip_env "no lru resize on server"
13841
13842         LIMIT=$(get_max_pool_limit)
13843
13844         NR=$(($(default_lru_size)*20))
13845         if [[ $NR -gt $LIMIT ]]; then
13846                 log "Limit lock number by $LIMIT locks"
13847                 NR=$LIMIT
13848         fi
13849
13850         IFree=$(mdsrate_inodes_available)
13851         if [ $IFree -lt $NR ]; then
13852                 log "Limit lock number by $IFree inodes"
13853                 NR=$IFree
13854         fi
13855
13856         lru_resize_disable mdc
13857         test_mkdir -p $DIR/$tdir/disable_lru_resize
13858
13859         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13860         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13861         cancel_lru_locks mdc
13862         stime=`date +%s`
13863         PID=""
13864         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13865         PID="$PID $!"
13866         sleep 2
13867         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13868         PID="$PID $!"
13869         sleep 2
13870         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13871         PID="$PID $!"
13872         wait $PID
13873         etime=`date +%s`
13874         nolruresize_delta=$((etime-stime))
13875         log "ls -la time: $nolruresize_delta seconds"
13876         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13877         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13878
13879         lru_resize_enable mdc
13880         test_mkdir -p $DIR/$tdir/enable_lru_resize
13881
13882         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13883         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13884         cancel_lru_locks mdc
13885         stime=`date +%s`
13886         PID=""
13887         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13888         PID="$PID $!"
13889         sleep 2
13890         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13891         PID="$PID $!"
13892         sleep 2
13893         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13894         PID="$PID $!"
13895         wait $PID
13896         etime=`date +%s`
13897         lruresize_delta=$((etime-stime))
13898         log "ls -la time: $lruresize_delta seconds"
13899         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13900
13901         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13902                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13903         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13904                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13905         else
13906                 log "lru resize performs the same with no lru resize"
13907         fi
13908         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13909 }
13910 run_test 124b "lru resize (performance test) ======================="
13911
13912 test_124c() {
13913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13914         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13915                 skip_env "no lru resize on server"
13916
13917         # cache ununsed locks on client
13918         local nr=100
13919         cancel_lru_locks mdc
13920         test_mkdir $DIR/$tdir
13921         createmany -o $DIR/$tdir/f $nr ||
13922                 error "failed to create $nr files in $DIR/$tdir"
13923         ls -l $DIR/$tdir > /dev/null
13924
13925         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13926         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13927         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13928         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13929         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13930
13931         # set lru_max_age to 1 sec
13932         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13933         echo "sleep $((recalc_p * 2)) seconds..."
13934         sleep $((recalc_p * 2))
13935
13936         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13937         # restore lru_max_age
13938         $LCTL set_param -n $nsdir.lru_max_age $max_age
13939         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13940         unlinkmany $DIR/$tdir/f $nr
13941 }
13942 run_test 124c "LRUR cancel very aged locks"
13943
13944 test_124d() {
13945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13946         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13947                 skip_env "no lru resize on server"
13948
13949         # cache ununsed locks on client
13950         local nr=100
13951
13952         lru_resize_disable mdc
13953         stack_trap "lru_resize_enable mdc" EXIT
13954
13955         cancel_lru_locks mdc
13956
13957         # asynchronous object destroy at MDT could cause bl ast to client
13958         test_mkdir $DIR/$tdir
13959         createmany -o $DIR/$tdir/f $nr ||
13960                 error "failed to create $nr files in $DIR/$tdir"
13961         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13962
13963         ls -l $DIR/$tdir > /dev/null
13964
13965         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13966         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13967         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13968         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13969
13970         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13971
13972         # set lru_max_age to 1 sec
13973         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13974         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13975
13976         echo "sleep $((recalc_p * 2)) seconds..."
13977         sleep $((recalc_p * 2))
13978
13979         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13980
13981         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13982 }
13983 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13984
13985 test_125() { # 13358
13986         $LCTL get_param -n llite.*.client_type | grep -q local ||
13987                 skip "must run as local client"
13988         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13989                 skip_env "must have acl enabled"
13990         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13991
13992         test_mkdir $DIR/$tdir
13993         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13994         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13995                 error "setfacl $DIR/$tdir failed"
13996         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13997 }
13998 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13999
14000 test_126() { # bug 12829/13455
14001         $GSS && skip_env "must run as gss disabled"
14002         $LCTL get_param -n llite.*.client_type | grep -q local ||
14003                 skip "must run as local client"
14004         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14005
14006         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14007         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14008         rm -f $DIR/$tfile
14009         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14010 }
14011 run_test 126 "check that the fsgid provided by the client is taken into account"
14012
14013 test_127a() { # bug 15521
14014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14015         local name count samp unit min max sum sumsq
14016         local tmpfile=$TMP/$tfile.tmp
14017
14018         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14019         echo "stats before reset"
14020         stack_trap "rm -f $tmpfile"
14021         local now=$(date +%s)
14022
14023         $LCTL get_param osc.*.stats | tee $tmpfile
14024
14025         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14026         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14027         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14028         local uptime=$(awk '{ print $1 }' /proc/uptime)
14029
14030         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14031         (( ${snapshot_time%\.*} >= $now - 5 &&
14032            ${snapshot_time%\.*} <= $now + 5 )) ||
14033                 error "snapshot_time=$snapshot_time != now=$now"
14034         # elapsed _should_ be from mount, but at least less than uptime
14035         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14036                 error "elapsed=$elapsed > uptime=$uptime"
14037         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14038            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14039                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14040
14041         $LCTL set_param osc.*.stats=0
14042         local reset=$(date +%s)
14043         local fsize=$((2048 * 1024))
14044
14045         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14046         cancel_lru_locks osc
14047         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14048
14049         now=$(date +%s)
14050         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14051         while read name count samp unit min max sum sumsq; do
14052                 [[ "$samp" == "samples" ]] || continue
14053
14054                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14055                 [ ! $min ] && error "Missing min value for $name proc entry"
14056                 eval $name=$count || error "Wrong proc format"
14057
14058                 case $name in
14059                 read_bytes|write_bytes)
14060                         [[ "$unit" =~ "bytes" ]] ||
14061                                 error "unit is not 'bytes': $unit"
14062                         (( $min >= 4096 )) || error "min is too small: $min"
14063                         (( $min <= $fsize )) || error "min is too big: $min"
14064                         (( $max >= 4096 )) || error "max is too small: $max"
14065                         (( $max <= $fsize )) || error "max is too big: $max"
14066                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14067                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14068                                 error "sumsquare is too small: $sumsq"
14069                         (( $sumsq <= $fsize * $fsize )) ||
14070                                 error "sumsquare is too big: $sumsq"
14071                         ;;
14072                 ost_read|ost_write)
14073                         [[ "$unit" =~ "usec" ]] ||
14074                                 error "unit is not 'usec': $unit"
14075                         ;;
14076                 *)      ;;
14077                 esac
14078         done < $tmpfile
14079
14080         #check that we actually got some stats
14081         [ "$read_bytes" ] || error "Missing read_bytes stats"
14082         [ "$write_bytes" ] || error "Missing write_bytes stats"
14083         [ "$read_bytes" != 0 ] || error "no read done"
14084         [ "$write_bytes" != 0 ] || error "no write done"
14085
14086         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14087         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14088         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14089
14090         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14091         (( ${snapshot_time%\.*} >= $now - 5 &&
14092            ${snapshot_time%\.*} <= $now + 5 )) ||
14093                 error "reset snapshot_time=$snapshot_time != now=$now"
14094         # elapsed should be from time of stats reset
14095         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14096            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14097                 error "reset elapsed=$elapsed > $now - $reset"
14098         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14099            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14100                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14101 }
14102 run_test 127a "verify the client stats are sane"
14103
14104 test_127b() { # bug LU-333
14105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14106         local name count samp unit min max sum sumsq
14107
14108         echo "stats before reset"
14109         $LCTL get_param llite.*.stats
14110         $LCTL set_param llite.*.stats=0
14111
14112         # perform 2 reads and writes so MAX is different from SUM.
14113         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14114         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14115         cancel_lru_locks osc
14116         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14117         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14118
14119         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14120         stack_trap "rm -f $TMP/$tfile.tmp"
14121         while read name count samp unit min max sum sumsq; do
14122                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14123                 eval $name=$count || error "Wrong proc format"
14124
14125                 case $name in
14126                 read_bytes|write_bytes)
14127                         [[ "$unit" =~ "bytes" ]] ||
14128                                 error "unit is not 'bytes': $unit"
14129                         (( $count == 2 )) || error "count is not 2: $count"
14130                         (( $min == $PAGE_SIZE )) ||
14131                                 error "min is not $PAGE_SIZE: $min"
14132                         (( $max == $PAGE_SIZE )) ||
14133                                 error "max is not $PAGE_SIZE: $max"
14134                         (( $sum == $PAGE_SIZE * 2 )) ||
14135                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14136                         ;;
14137                 read|write)
14138                         [[ "$unit" =~ "usec" ]] ||
14139                                 error "unit is not 'usec': $unit"
14140                         ;;
14141                 *)      ;;
14142                 esac
14143         done < $TMP/$tfile.tmp
14144
14145         #check that we actually got some stats
14146         [ "$read_bytes" ] || error "Missing read_bytes stats"
14147         [ "$write_bytes" ] || error "Missing write_bytes stats"
14148         [ "$read_bytes" != 0 ] || error "no read done"
14149         [ "$write_bytes" != 0 ] || error "no write done"
14150 }
14151 run_test 127b "verify the llite client stats are sane"
14152
14153 test_127c() { # LU-12394
14154         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14155         local size
14156         local bsize
14157         local reads
14158         local writes
14159         local count
14160
14161         $LCTL set_param llite.*.extents_stats=1
14162         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14163
14164         # Use two stripes so there is enough space in default config
14165         $LFS setstripe -c 2 $DIR/$tfile
14166
14167         # Extent stats start at 0-4K and go in power of two buckets
14168         # LL_HIST_START = 12 --> 2^12 = 4K
14169         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14170         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14171         # small configs
14172         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14173                 do
14174                 # Write and read, 2x each, second time at a non-zero offset
14175                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14176                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14177                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14178                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14179                 rm -f $DIR/$tfile
14180         done
14181
14182         $LCTL get_param llite.*.extents_stats
14183
14184         count=2
14185         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14186                 do
14187                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14188                                 grep -m 1 $bsize)
14189                 reads=$(echo $bucket | awk '{print $5}')
14190                 writes=$(echo $bucket | awk '{print $9}')
14191                 [ "$reads" -eq $count ] ||
14192                         error "$reads reads in < $bsize bucket, expect $count"
14193                 [ "$writes" -eq $count ] ||
14194                         error "$writes writes in < $bsize bucket, expect $count"
14195         done
14196
14197         # Test mmap write and read
14198         $LCTL set_param llite.*.extents_stats=c
14199         size=512
14200         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14201         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14202         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14203
14204         $LCTL get_param llite.*.extents_stats
14205
14206         count=$(((size*1024) / PAGE_SIZE))
14207
14208         bsize=$((2 * PAGE_SIZE / 1024))K
14209
14210         bucket=$($LCTL get_param -n llite.*.extents_stats |
14211                         grep -m 1 $bsize)
14212         reads=$(echo $bucket | awk '{print $5}')
14213         writes=$(echo $bucket | awk '{print $9}')
14214         # mmap writes fault in the page first, creating an additonal read
14215         [ "$reads" -eq $((2 * count)) ] ||
14216                 error "$reads reads in < $bsize bucket, expect $count"
14217         [ "$writes" -eq $count ] ||
14218                 error "$writes writes in < $bsize bucket, expect $count"
14219 }
14220 run_test 127c "test llite extent stats with regular & mmap i/o"
14221
14222 test_128() { # bug 15212
14223         touch $DIR/$tfile
14224         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14225                 find $DIR/$tfile
14226                 find $DIR/$tfile
14227         EOF
14228
14229         result=$(grep error $TMP/$tfile.log)
14230         rm -f $DIR/$tfile $TMP/$tfile.log
14231         [ -z "$result" ] ||
14232                 error "consecutive find's under interactive lfs failed"
14233 }
14234 run_test 128 "interactive lfs for 2 consecutive find's"
14235
14236 set_dir_limits () {
14237         local mntdev
14238         local canondev
14239         local node
14240
14241         local ldproc=/proc/fs/ldiskfs
14242         local facets=$(get_facets MDS)
14243
14244         for facet in ${facets//,/ }; do
14245                 canondev=$(ldiskfs_canon \
14246                            *.$(convert_facet2label $facet).mntdev $facet)
14247                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14248                         ldproc=/sys/fs/ldiskfs
14249                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14250                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14251         done
14252 }
14253
14254 check_mds_dmesg() {
14255         local facets=$(get_facets MDS)
14256         for facet in ${facets//,/ }; do
14257                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14258         done
14259         return 1
14260 }
14261
14262 test_129() {
14263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14264         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14265                 skip "Need MDS version with at least 2.5.56"
14266         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14267                 skip_env "ldiskfs only test"
14268         fi
14269         remote_mds_nodsh && skip "remote MDS with nodsh"
14270
14271         local ENOSPC=28
14272         local has_warning=false
14273
14274         rm -rf $DIR/$tdir
14275         mkdir -p $DIR/$tdir
14276
14277         # block size of mds1
14278         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14279         set_dir_limits $maxsize $((maxsize * 6 / 8))
14280         stack_trap "set_dir_limits 0 0"
14281         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14282         local dirsize=$(stat -c%s "$DIR/$tdir")
14283         local nfiles=0
14284         while (( $dirsize <= $maxsize )); do
14285                 $MCREATE $DIR/$tdir/file_base_$nfiles
14286                 rc=$?
14287                 # check two errors:
14288                 # ENOSPC for ext4 max_dir_size, which has been used since
14289                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14290                 if (( rc == ENOSPC )); then
14291                         set_dir_limits 0 0
14292                         echo "rc=$rc returned as expected after $nfiles files"
14293
14294                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14295                                 error "create failed w/o dir size limit"
14296
14297                         # messages may be rate limited if test is run repeatedly
14298                         check_mds_dmesg '"is approaching max"' ||
14299                                 echo "warning message should be output"
14300                         check_mds_dmesg '"has reached max"' ||
14301                                 echo "reached message should be output"
14302
14303                         dirsize=$(stat -c%s "$DIR/$tdir")
14304
14305                         [[ $dirsize -ge $maxsize ]] && return 0
14306                         error "dirsize $dirsize < $maxsize after $nfiles files"
14307                 elif (( rc != 0 )); then
14308                         break
14309                 fi
14310                 nfiles=$((nfiles + 1))
14311                 dirsize=$(stat -c%s "$DIR/$tdir")
14312         done
14313
14314         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14315 }
14316 run_test 129 "test directory size limit ========================"
14317
14318 OLDIFS="$IFS"
14319 cleanup_130() {
14320         trap 0
14321         IFS="$OLDIFS"
14322 }
14323
14324 test_130a() {
14325         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14326         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14327
14328         trap cleanup_130 EXIT RETURN
14329
14330         local fm_file=$DIR/$tfile
14331         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14332         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14333                 error "dd failed for $fm_file"
14334
14335         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14336         filefrag -ves $fm_file
14337         local rc=$?
14338         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14339                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14340         (( $rc == 0 )) || error "filefrag $fm_file failed"
14341
14342         filefrag_op=$(filefrag -ve -k $fm_file |
14343                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14344         local lun=$($LFS getstripe -i $fm_file)
14345
14346         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14347         IFS=$'\n'
14348         local tot_len=0
14349         for line in $filefrag_op; do
14350                 local frag_lun=$(echo $line | cut -d: -f5)
14351                 local ext_len=$(echo $line | cut -d: -f4)
14352
14353                 if (( $frag_lun != $lun )); then
14354                         error "FIEMAP on 1-stripe file($fm_file) failed"
14355                         return
14356                 fi
14357                 (( tot_len += ext_len ))
14358         done
14359
14360         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14361                 error "FIEMAP on 1-stripe file($fm_file) failed"
14362                 return
14363         fi
14364
14365         echo "FIEMAP on single striped file succeeded"
14366 }
14367 run_test 130a "FIEMAP (1-stripe file)"
14368
14369 test_130b() {
14370         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14371
14372         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14373         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14374         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14375                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14376
14377         trap cleanup_130 EXIT RETURN
14378
14379         local fm_file=$DIR/$tfile
14380         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14381                 error "setstripe on $fm_file"
14382
14383         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14384                 error "dd failed on $fm_file"
14385
14386         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14387         filefrag_op=$(filefrag -ve -k $fm_file |
14388                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14389
14390         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14391                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14392
14393         IFS=$'\n'
14394         local tot_len=0
14395         local num_luns=1
14396
14397         for line in $filefrag_op; do
14398                 local frag_lun=$(echo $line | cut -d: -f5 |
14399                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14400                 local ext_len=$(echo $line | cut -d: -f4)
14401                 if (( $frag_lun != $last_lun )); then
14402                         if (( tot_len != 1024 )); then
14403                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14404                                 return
14405                         else
14406                                 (( num_luns += 1 ))
14407                                 tot_len=0
14408                         fi
14409                 fi
14410                 (( tot_len += ext_len ))
14411                 last_lun=$frag_lun
14412         done
14413         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14414                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14415                 return
14416         fi
14417
14418         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14419 }
14420 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14421
14422 test_130c() {
14423         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14424
14425         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14426         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14427         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14428                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14429
14430         trap cleanup_130 EXIT RETURN
14431
14432         local fm_file=$DIR/$tfile
14433         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14434
14435         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14436                 error "dd failed on $fm_file"
14437
14438         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14439         filefrag_op=$(filefrag -ve -k $fm_file |
14440                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14441
14442         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14443                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14444
14445         IFS=$'\n'
14446         local tot_len=0
14447         local num_luns=1
14448         for line in $filefrag_op; do
14449                 local frag_lun=$(echo $line | cut -d: -f5 |
14450                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14451                 local ext_len=$(echo $line | cut -d: -f4)
14452                 if (( $frag_lun != $last_lun )); then
14453                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14454                         if (( logical != 512 )); then
14455                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14456                                 return
14457                         fi
14458                         if (( tot_len != 512 )); then
14459                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14460                                 return
14461                         else
14462                                 (( num_luns += 1 ))
14463                                 tot_len=0
14464                         fi
14465                 fi
14466                 (( tot_len += ext_len ))
14467                 last_lun=$frag_lun
14468         done
14469         if (( num_luns != 2 || tot_len != 512 )); then
14470                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14471                 return
14472         fi
14473
14474         echo "FIEMAP on 2-stripe file with hole succeeded"
14475 }
14476 run_test 130c "FIEMAP (2-stripe file with hole)"
14477
14478 test_130d() {
14479         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14480
14481         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14482         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14483         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14484                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14485
14486         trap cleanup_130 EXIT RETURN
14487
14488         local fm_file=$DIR/$tfile
14489         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14490                         error "setstripe on $fm_file"
14491
14492         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14493         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14494                 error "dd failed on $fm_file"
14495
14496         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14497         filefrag_op=$(filefrag -ve -k $fm_file |
14498                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14499
14500         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14501                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14502
14503         IFS=$'\n'
14504         local tot_len=0
14505         local num_luns=1
14506         for line in $filefrag_op; do
14507                 local frag_lun=$(echo $line | cut -d: -f5 |
14508                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14509                 local ext_len=$(echo $line | cut -d: -f4)
14510                 if (( $frag_lun != $last_lun )); then
14511                         if (( tot_len != 1024 )); then
14512                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14513                                 return
14514                         else
14515                                 (( num_luns += 1 ))
14516                                 local tot_len=0
14517                         fi
14518                 fi
14519                 (( tot_len += ext_len ))
14520                 last_lun=$frag_lun
14521         done
14522         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14523                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14524                 return
14525         fi
14526
14527         echo "FIEMAP on N-stripe file succeeded"
14528 }
14529 run_test 130d "FIEMAP (N-stripe file)"
14530
14531 test_130e() {
14532         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14533
14534         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14535         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14536         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14537                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14538
14539         trap cleanup_130 EXIT RETURN
14540
14541         local fm_file=$DIR/$tfile
14542         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14543
14544         local num_blks=512
14545         local expected_len=$(( (num_blks / 2) * 64 ))
14546         for ((i = 0; i < $num_blks; i++)); do
14547                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14548                         conv=notrunc > /dev/null 2>&1
14549         done
14550
14551         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14552         filefrag_op=$(filefrag -ve -k $fm_file |
14553                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14554
14555         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14556
14557         IFS=$'\n'
14558         local tot_len=0
14559         local num_luns=1
14560         for line in $filefrag_op; do
14561                 local frag_lun=$(echo $line | cut -d: -f5)
14562                 local ext_len=$(echo $line | cut -d: -f4)
14563                 if (( $frag_lun != $last_lun )); then
14564                         if (( tot_len != $expected_len )); then
14565                                 error "OST$last_lun $tot_len != $expected_len"
14566                         else
14567                                 (( num_luns += 1 ))
14568                                 tot_len=0
14569                         fi
14570                 fi
14571                 (( tot_len += ext_len ))
14572                 last_lun=$frag_lun
14573         done
14574         if (( num_luns != 2 || tot_len != $expected_len )); then
14575                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14576         fi
14577
14578         echo "FIEMAP with continuation calls succeeded"
14579 }
14580 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14581
14582 test_130f() {
14583         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14584         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14585         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14586                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14587
14588         local fm_file=$DIR/$tfile
14589         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14590                 error "multiop create with lov_delay_create on $fm_file"
14591
14592         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14593         filefrag_extents=$(filefrag -vek $fm_file |
14594                            awk '/extents? found/ { print $2 }')
14595         if (( $filefrag_extents != 0 )); then
14596                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14597         fi
14598
14599         rm -f $fm_file
14600 }
14601 run_test 130f "FIEMAP (unstriped file)"
14602
14603 test_130g() {
14604         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14605                 skip "Need MDS version with at least 2.12.53 for overstriping"
14606         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14607         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14608         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14609                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14610
14611         local file=$DIR/$tfile
14612         local nr=$((OSTCOUNT * 100))
14613
14614         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14615
14616         stack_trap "rm -f $file"
14617         dd if=/dev/zero of=$file count=$nr bs=1M
14618         sync
14619         nr=$($LFS getstripe -c $file)
14620
14621         local extents=$(filefrag -v $file |
14622                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14623
14624         echo "filefrag list $extents extents in file with stripecount $nr"
14625         if (( extents < nr )); then
14626                 $LFS getstripe $file
14627                 filefrag -v $file
14628                 error "filefrag printed $extents < $nr extents"
14629         fi
14630 }
14631 run_test 130g "FIEMAP (overstripe file)"
14632
14633 # Test for writev/readv
14634 test_131a() {
14635         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14636                 error "writev test failed"
14637         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14638                 error "readv failed"
14639         rm -f $DIR/$tfile
14640 }
14641 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14642
14643 test_131b() {
14644         local fsize=$((524288 + 1048576 + 1572864))
14645         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14646                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14647                         error "append writev test failed"
14648
14649         ((fsize += 1572864 + 1048576))
14650         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14651                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14652                         error "append writev test failed"
14653         rm -f $DIR/$tfile
14654 }
14655 run_test 131b "test append writev"
14656
14657 test_131c() {
14658         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14659         error "NOT PASS"
14660 }
14661 run_test 131c "test read/write on file w/o objects"
14662
14663 test_131d() {
14664         rwv -f $DIR/$tfile -w -n 1 1572864
14665         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14666         if [ "$NOB" != 1572864 ]; then
14667                 error "Short read filed: read $NOB bytes instead of 1572864"
14668         fi
14669         rm -f $DIR/$tfile
14670 }
14671 run_test 131d "test short read"
14672
14673 test_131e() {
14674         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14675         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14676         error "read hitting hole failed"
14677         rm -f $DIR/$tfile
14678 }
14679 run_test 131e "test read hitting hole"
14680
14681 check_stats() {
14682         local facet=$1
14683         local op=$2
14684         local want=${3:-0}
14685         local res
14686
14687         # open             11 samples [usecs] 468 4793 13658 35791898
14688         case $facet in
14689         mds*) res=($(do_facet $facet \
14690                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14691                  ;;
14692         ost*) res=($(do_facet $facet \
14693                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14694                  ;;
14695         *) error "Wrong facet '$facet'" ;;
14696         esac
14697         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14698         # if $want is zero, it means any stat increment is ok.
14699         if (( $want > 0 )); then
14700                 local count=${res[1]}
14701
14702                 if (( $count != $want )); then
14703                         if [[ $facet =~ "mds" ]]; then
14704                                 do_nodes $(comma_list $(mdts_nodes)) \
14705                                         $LCTL get_param mdt.*.md_stats
14706                         else
14707                                 do_nodes $(comma_list $(osts-nodes)) \
14708                                         $LCTL get_param obdfilter.*.stats
14709                         fi
14710                         error "The $op counter on $facet is $count, not $want"
14711                 fi
14712         fi
14713 }
14714
14715 test_133a() {
14716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14717         remote_ost_nodsh && skip "remote OST with nodsh"
14718         remote_mds_nodsh && skip "remote MDS with nodsh"
14719         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14720                 skip_env "MDS doesn't support rename stats"
14721
14722         local testdir=$DIR/${tdir}/stats_testdir
14723
14724         mkdir -p $DIR/${tdir}
14725
14726         # clear stats.
14727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14728         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14729
14730         # verify mdt stats first.
14731         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14732         check_stats $SINGLEMDS "mkdir" 1
14733
14734         # clear "open" from "lfs mkdir" above
14735         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14736         touch ${testdir}/${tfile} || error "touch failed"
14737         check_stats $SINGLEMDS "open" 1
14738         check_stats $SINGLEMDS "close" 1
14739         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14740                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14741                 check_stats $SINGLEMDS "mknod" 2
14742         }
14743         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14744         check_stats $SINGLEMDS "unlink" 1
14745         rm -f ${testdir}/${tfile} || error "file remove failed"
14746         check_stats $SINGLEMDS "unlink" 2
14747
14748         # remove working dir and check mdt stats again.
14749         rmdir ${testdir} || error "rmdir failed"
14750         check_stats $SINGLEMDS "rmdir" 1
14751
14752         local testdir1=$DIR/${tdir}/stats_testdir1
14753         mkdir_on_mdt0 -p ${testdir}
14754         mkdir_on_mdt0 -p ${testdir1}
14755         touch ${testdir1}/test1
14756         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14757         check_stats $SINGLEMDS "crossdir_rename" 1
14758
14759         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14760         check_stats $SINGLEMDS "samedir_rename" 1
14761
14762         rm -rf $DIR/${tdir}
14763 }
14764 run_test 133a "Verifying MDT stats ========================================"
14765
14766 test_133b() {
14767         local res
14768
14769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14770         remote_ost_nodsh && skip "remote OST with nodsh"
14771         remote_mds_nodsh && skip "remote MDS with nodsh"
14772
14773         local testdir=$DIR/${tdir}/stats_testdir
14774
14775         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14776         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14777         touch ${testdir}/${tfile} || error "touch failed"
14778         cancel_lru_locks mdc
14779
14780         # clear stats.
14781         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14782         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14783
14784         # extra mdt stats verification.
14785         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14786         check_stats $SINGLEMDS "setattr" 1
14787         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14788         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14789         then            # LU-1740
14790                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14791                 check_stats $SINGLEMDS "getattr" 1
14792         fi
14793         rm -rf $DIR/${tdir}
14794
14795         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14796         # so the check below is not reliable
14797         [ $MDSCOUNT -eq 1 ] || return 0
14798
14799         # Sleep to avoid a cached response.
14800         #define OBD_STATFS_CACHE_SECONDS 1
14801         sleep 2
14802         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14803         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14804         $LFS df || error "lfs failed"
14805         check_stats $SINGLEMDS "statfs" 1
14806
14807         # check aggregated statfs (LU-10018)
14808         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14809                 return 0
14810         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14811                 return 0
14812         sleep 2
14813         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14814         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14815         df $DIR
14816         check_stats $SINGLEMDS "statfs" 1
14817
14818         # We want to check that the client didn't send OST_STATFS to
14819         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14820         # extra care is needed here.
14821         if remote_mds; then
14822                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14823                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14824
14825                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14826                 [ "$res" ] && error "OST got STATFS"
14827         fi
14828
14829         return 0
14830 }
14831 run_test 133b "Verifying extra MDT stats =================================="
14832
14833 test_133c() {
14834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14835         remote_ost_nodsh && skip "remote OST with nodsh"
14836         remote_mds_nodsh && skip "remote MDS with nodsh"
14837
14838         local testdir=$DIR/$tdir/stats_testdir
14839
14840         test_mkdir -p $testdir
14841
14842         # verify obdfilter stats.
14843         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14844         sync
14845         cancel_lru_locks osc
14846         wait_delete_completed
14847
14848         # clear stats.
14849         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14850         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14851
14852         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14853                 error "dd failed"
14854         sync
14855         cancel_lru_locks osc
14856         check_stats ost1 "write" 1
14857
14858         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14859         check_stats ost1 "read" 1
14860
14861         > $testdir/$tfile || error "truncate failed"
14862         check_stats ost1 "punch" 1
14863
14864         rm -f $testdir/$tfile || error "file remove failed"
14865         wait_delete_completed
14866         check_stats ost1 "destroy" 1
14867
14868         rm -rf $DIR/$tdir
14869 }
14870 run_test 133c "Verifying OST stats ========================================"
14871
14872 order_2() {
14873         local value=$1
14874         local orig=$value
14875         local order=1
14876
14877         while [ $value -ge 2 ]; do
14878                 order=$((order*2))
14879                 value=$((value/2))
14880         done
14881
14882         if [ $orig -gt $order ]; then
14883                 order=$((order*2))
14884         fi
14885         echo $order
14886 }
14887
14888 size_in_KMGT() {
14889     local value=$1
14890     local size=('K' 'M' 'G' 'T');
14891     local i=0
14892     local size_string=$value
14893
14894     while [ $value -ge 1024 ]; do
14895         if [ $i -gt 3 ]; then
14896             #T is the biggest unit we get here, if that is bigger,
14897             #just return XXXT
14898             size_string=${value}T
14899             break
14900         fi
14901         value=$((value >> 10))
14902         if [ $value -lt 1024 ]; then
14903             size_string=${value}${size[$i]}
14904             break
14905         fi
14906         i=$((i + 1))
14907     done
14908
14909     echo $size_string
14910 }
14911
14912 get_rename_size() {
14913         local size=$1
14914         local context=${2:-.}
14915         local sample=$(do_facet $SINGLEMDS $LCTL \
14916                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14917                 grep -A1 $context |
14918                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14919         echo $sample
14920 }
14921
14922 test_133d() {
14923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14924         remote_ost_nodsh && skip "remote OST with nodsh"
14925         remote_mds_nodsh && skip "remote MDS with nodsh"
14926         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14927                 skip_env "MDS doesn't support rename stats"
14928
14929         local testdir1=$DIR/${tdir}/stats_testdir1
14930         local testdir2=$DIR/${tdir}/stats_testdir2
14931         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14932
14933         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14934
14935         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14936         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14937
14938         createmany -o $testdir1/test 512 || error "createmany failed"
14939
14940         # check samedir rename size
14941         mv ${testdir1}/test0 ${testdir1}/test_0
14942
14943         local testdir1_size=$(ls -l $DIR/${tdir} |
14944                 awk '/stats_testdir1/ {print $5}')
14945         local testdir2_size=$(ls -l $DIR/${tdir} |
14946                 awk '/stats_testdir2/ {print $5}')
14947
14948         testdir1_size=$(order_2 $testdir1_size)
14949         testdir2_size=$(order_2 $testdir2_size)
14950
14951         testdir1_size=$(size_in_KMGT $testdir1_size)
14952         testdir2_size=$(size_in_KMGT $testdir2_size)
14953
14954         echo "source rename dir size: ${testdir1_size}"
14955         echo "target rename dir size: ${testdir2_size}"
14956
14957         local cmd="do_facet $SINGLEMDS $LCTL "
14958         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14959
14960         eval $cmd || error "$cmd failed"
14961         local samedir=$($cmd | grep 'same_dir')
14962         local same_sample=$(get_rename_size $testdir1_size)
14963         [ -z "$samedir" ] && error "samedir_rename_size count error"
14964         [[ $same_sample -eq 1 ]] ||
14965                 error "samedir_rename_size error $same_sample"
14966         echo "Check same dir rename stats success"
14967
14968         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14969
14970         # check crossdir rename size
14971         mv ${testdir1}/test_0 ${testdir2}/test_0
14972
14973         testdir1_size=$(ls -l $DIR/${tdir} |
14974                 awk '/stats_testdir1/ {print $5}')
14975         testdir2_size=$(ls -l $DIR/${tdir} |
14976                 awk '/stats_testdir2/ {print $5}')
14977
14978         testdir1_size=$(order_2 $testdir1_size)
14979         testdir2_size=$(order_2 $testdir2_size)
14980
14981         testdir1_size=$(size_in_KMGT $testdir1_size)
14982         testdir2_size=$(size_in_KMGT $testdir2_size)
14983
14984         echo "source rename dir size: ${testdir1_size}"
14985         echo "target rename dir size: ${testdir2_size}"
14986
14987         eval $cmd || error "$cmd failed"
14988         local crossdir=$($cmd | grep 'crossdir')
14989         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14990         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14991         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14992         [[ $src_sample -eq 1 ]] ||
14993                 error "crossdir_rename_size error $src_sample"
14994         [[ $tgt_sample -eq 1 ]] ||
14995                 error "crossdir_rename_size error $tgt_sample"
14996         echo "Check cross dir rename stats success"
14997         rm -rf $DIR/${tdir}
14998 }
14999 run_test 133d "Verifying rename_stats ========================================"
15000
15001 test_133e() {
15002         remote_mds_nodsh && skip "remote MDS with nodsh"
15003         remote_ost_nodsh && skip "remote OST with nodsh"
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005
15006         local testdir=$DIR/${tdir}/stats_testdir
15007         local ctr f0 f1 bs=32768 count=42 sum
15008
15009         mkdir -p ${testdir} || error "mkdir failed"
15010
15011         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15012
15013         for ctr in {write,read}_bytes; do
15014                 sync
15015                 cancel_lru_locks osc
15016
15017                 do_facet ost1 $LCTL set_param -n \
15018                         "obdfilter.*.exports.clear=clear"
15019
15020                 if [ $ctr = write_bytes ]; then
15021                         f0=/dev/zero
15022                         f1=${testdir}/${tfile}
15023                 else
15024                         f0=${testdir}/${tfile}
15025                         f1=/dev/null
15026                 fi
15027
15028                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15029                         error "dd failed"
15030                 sync
15031                 cancel_lru_locks osc
15032
15033                 sum=$(do_facet ost1 $LCTL get_param \
15034                         "obdfilter.*.exports.*.stats" |
15035                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15036                                 $1 == ctr { sum += $7 }
15037                                 END { printf("%0.0f", sum) }')
15038
15039                 if ((sum != bs * count)); then
15040                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15041                 fi
15042         done
15043
15044         rm -rf $DIR/${tdir}
15045 }
15046 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15047
15048 test_133f() {
15049         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15050                 skip "too old lustre for get_param -R ($facet_ver)"
15051
15052         # verifying readability.
15053         $LCTL get_param -R '*' &> /dev/null
15054
15055         # Verifing writability with badarea_io.
15056         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15057         local skipped_params='force_lbug|changelog_mask|daemon_file'
15058         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15059                 egrep -v "$skipped_params" |
15060                 xargs -n 1 find $proc_dirs -name |
15061                 xargs -n 1 badarea_io ||
15062                 error "client badarea_io failed"
15063
15064         # remount the FS in case writes/reads /proc break the FS
15065         cleanup || error "failed to unmount"
15066         setup || error "failed to setup"
15067 }
15068 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15069
15070 test_133g() {
15071         remote_mds_nodsh && skip "remote MDS with nodsh"
15072         remote_ost_nodsh && skip "remote OST with nodsh"
15073
15074         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15075         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15076         local facet
15077         for facet in mds1 ost1; do
15078                 local facet_ver=$(lustre_version_code $facet)
15079                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15080                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15081                 else
15082                         log "$facet: too old lustre for get_param -R"
15083                 fi
15084                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15085                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15086                                 tr -d = | egrep -v $skipped_params |
15087                                 xargs -n 1 find $proc_dirs -name |
15088                                 xargs -n 1 badarea_io" ||
15089                                         error "$facet badarea_io failed"
15090                 else
15091                         skip_noexit "$facet: too old lustre for get_param -R"
15092                 fi
15093         done
15094
15095         # remount the FS in case writes/reads /proc break the FS
15096         cleanup || error "failed to unmount"
15097         setup || error "failed to setup"
15098 }
15099 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15100
15101 test_133h() {
15102         remote_mds_nodsh && skip "remote MDS with nodsh"
15103         remote_ost_nodsh && skip "remote OST with nodsh"
15104         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15105                 skip "Need MDS version at least 2.9.54"
15106
15107         local facet
15108         for facet in client mds1 ost1; do
15109                 # Get the list of files that are missing the terminating newline
15110                 local plist=$(do_facet $facet
15111                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15112                 local ent
15113                 for ent in $plist; do
15114                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15115                                 awk -v FS='\v' -v RS='\v\v' \
15116                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15117                                         print FILENAME}'" 2>/dev/null)
15118                         [ -z $missing ] || {
15119                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15120                                 error "file does not end with newline: $facet-$ent"
15121                         }
15122                 done
15123         done
15124 }
15125 run_test 133h "Proc files should end with newlines"
15126
15127 test_134a() {
15128         remote_mds_nodsh && skip "remote MDS with nodsh"
15129         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15130                 skip "Need MDS version at least 2.7.54"
15131
15132         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15133         cancel_lru_locks mdc
15134
15135         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15136         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15137         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15138
15139         local nr=1000
15140         createmany -o $DIR/$tdir/f $nr ||
15141                 error "failed to create $nr files in $DIR/$tdir"
15142         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15143
15144         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15145         do_facet mds1 $LCTL set_param fail_loc=0x327
15146         do_facet mds1 $LCTL set_param fail_val=500
15147         touch $DIR/$tdir/m
15148
15149         echo "sleep 10 seconds ..."
15150         sleep 10
15151         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15152
15153         do_facet mds1 $LCTL set_param fail_loc=0
15154         do_facet mds1 $LCTL set_param fail_val=0
15155         [ $lck_cnt -lt $unused ] ||
15156                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15157
15158         rm $DIR/$tdir/m
15159         unlinkmany $DIR/$tdir/f $nr
15160 }
15161 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15162
15163 test_134b() {
15164         remote_mds_nodsh && skip "remote MDS with nodsh"
15165         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15166                 skip "Need MDS version at least 2.7.54"
15167
15168         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15169         cancel_lru_locks mdc
15170
15171         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15172                         ldlm.lock_reclaim_threshold_mb)
15173         # disable reclaim temporarily
15174         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15175
15176         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15177         do_facet mds1 $LCTL set_param fail_loc=0x328
15178         do_facet mds1 $LCTL set_param fail_val=500
15179
15180         $LCTL set_param debug=+trace
15181
15182         local nr=600
15183         createmany -o $DIR/$tdir/f $nr &
15184         local create_pid=$!
15185
15186         echo "Sleep $TIMEOUT seconds ..."
15187         sleep $TIMEOUT
15188         if ! ps -p $create_pid  > /dev/null 2>&1; then
15189                 do_facet mds1 $LCTL set_param fail_loc=0
15190                 do_facet mds1 $LCTL set_param fail_val=0
15191                 do_facet mds1 $LCTL set_param \
15192                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15193                 error "createmany finished incorrectly!"
15194         fi
15195         do_facet mds1 $LCTL set_param fail_loc=0
15196         do_facet mds1 $LCTL set_param fail_val=0
15197         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15198         wait $create_pid || return 1
15199
15200         unlinkmany $DIR/$tdir/f $nr
15201 }
15202 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15203
15204 test_135() {
15205         remote_mds_nodsh && skip "remote MDS with nodsh"
15206         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15207                 skip "Need MDS version at least 2.13.50"
15208         local fname
15209
15210         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15211
15212 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15213         #set only one record at plain llog
15214         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15215
15216         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15217
15218         #fill already existed plain llog each 64767
15219         #wrapping whole catalog
15220         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15221
15222         createmany -o $DIR/$tdir/$tfile_ 64700
15223         for (( i = 0; i < 64700; i = i + 2 ))
15224         do
15225                 rm $DIR/$tdir/$tfile_$i &
15226                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15227                 local pid=$!
15228                 wait $pid
15229         done
15230
15231         #waiting osp synchronization
15232         wait_delete_completed
15233 }
15234 run_test 135 "Race catalog processing"
15235
15236 test_136() {
15237         remote_mds_nodsh && skip "remote MDS with nodsh"
15238         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15239                 skip "Need MDS version at least 2.13.50"
15240         local fname
15241
15242         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15243         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15244         #set only one record at plain llog
15245 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15246         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15247
15248         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15249
15250         #fill already existed 2 plain llogs each 64767
15251         #wrapping whole catalog
15252         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15253         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15254         wait_delete_completed
15255
15256         createmany -o $DIR/$tdir/$tfile_ 10
15257         sleep 25
15258
15259         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15260         for (( i = 0; i < 10; i = i + 3 ))
15261         do
15262                 rm $DIR/$tdir/$tfile_$i &
15263                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15264                 local pid=$!
15265                 wait $pid
15266                 sleep 7
15267                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15268         done
15269
15270         #waiting osp synchronization
15271         wait_delete_completed
15272 }
15273 run_test 136 "Race catalog processing 2"
15274
15275 test_140() { #bug-17379
15276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15277
15278         test_mkdir $DIR/$tdir
15279         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15280         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15281
15282         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15283         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15284         local i=0
15285         while i=$((i + 1)); do
15286                 test_mkdir $i
15287                 cd $i || error "Changing to $i"
15288                 ln -s ../stat stat || error "Creating stat symlink"
15289                 # Read the symlink until ELOOP present,
15290                 # not LBUGing the system is considered success,
15291                 # we didn't overrun the stack.
15292                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15293                 if [ $ret -ne 0 ]; then
15294                         if [ $ret -eq 40 ]; then
15295                                 break  # -ELOOP
15296                         else
15297                                 error "Open stat symlink"
15298                                         return
15299                         fi
15300                 fi
15301         done
15302         i=$((i - 1))
15303         echo "The symlink depth = $i"
15304         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15305                 error "Invalid symlink depth"
15306
15307         # Test recursive symlink
15308         ln -s symlink_self symlink_self
15309         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15310         echo "open symlink_self returns $ret"
15311         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15312 }
15313 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15314
15315 test_150a() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317
15318         local TF="$TMP/$tfile"
15319
15320         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15321         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15322         cp $TF $DIR/$tfile
15323         cancel_lru_locks $OSC
15324         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15325         remount_client $MOUNT
15326         df -P $MOUNT
15327         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15328
15329         $TRUNCATE $TF 6000
15330         $TRUNCATE $DIR/$tfile 6000
15331         cancel_lru_locks $OSC
15332         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15333
15334         echo "12345" >>$TF
15335         echo "12345" >>$DIR/$tfile
15336         cancel_lru_locks $OSC
15337         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15338
15339         echo "12345" >>$TF
15340         echo "12345" >>$DIR/$tfile
15341         cancel_lru_locks $OSC
15342         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15343 }
15344 run_test 150a "truncate/append tests"
15345
15346 test_150b() {
15347         check_set_fallocate_or_skip
15348         local out
15349
15350         touch $DIR/$tfile
15351         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15352         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15353                 skip_eopnotsupp "$out|check_fallocate failed"
15354 }
15355 run_test 150b "Verify fallocate (prealloc) functionality"
15356
15357 test_150bb() {
15358         check_set_fallocate_or_skip
15359
15360         touch $DIR/$tfile
15361         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15362         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15363         > $DIR/$tfile
15364         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15365         # precomputed md5sum for 20MB of zeroes
15366         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15367         local sum=($(md5sum $DIR/$tfile))
15368
15369         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15370
15371         check_set_fallocate 1
15372
15373         > $DIR/$tfile
15374         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15375         sum=($(md5sum $DIR/$tfile))
15376
15377         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15378 }
15379 run_test 150bb "Verify fallocate modes both zero space"
15380
15381 test_150c() {
15382         check_set_fallocate_or_skip
15383         local striping="-c2"
15384
15385         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15386         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15387         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15388         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15389         local want=$((OSTCOUNT * 1048576))
15390
15391         # Must allocate all requested space, not more than 5% extra
15392         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15393                 error "bytes $bytes is not $want"
15394
15395         rm -f $DIR/$tfile
15396
15397         echo "verify fallocate on PFL file"
15398
15399         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15400
15401         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15402                 error "Create $DIR/$tfile failed"
15403         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15404         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15405         want=$((512 * 1048576))
15406
15407         # Must allocate all requested space, not more than 5% extra
15408         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15409                 error "bytes $bytes is not $want"
15410 }
15411 run_test 150c "Verify fallocate Size and Blocks"
15412
15413 test_150d() {
15414         check_set_fallocate_or_skip
15415         local striping="-c2"
15416
15417         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15418
15419         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15420         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15421                 error "setstripe failed"
15422         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15423         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15424         local want=$((OSTCOUNT * 1048576))
15425
15426         # Must allocate all requested space, not more than 5% extra
15427         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15428                 error "bytes $bytes is not $want"
15429 }
15430 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15431
15432 test_150e() {
15433         check_set_fallocate_or_skip
15434
15435         echo "df before:"
15436         $LFS df
15437         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15438         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15439                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15440
15441         # Find OST with Minimum Size
15442         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15443                        sort -un | head -1)
15444
15445         # Get 100MB per OST of the available space to reduce run time
15446         # else 60% of the available space if we are running SLOW tests
15447         if [ $SLOW == "no" ]; then
15448                 local space=$((1024 * 100 * OSTCOUNT))
15449         else
15450                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15451         fi
15452
15453         fallocate -l${space}k $DIR/$tfile ||
15454                 error "fallocate ${space}k $DIR/$tfile failed"
15455         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15456
15457         # get size immediately after fallocate. This should be correctly
15458         # updated
15459         local size=$(stat -c '%s' $DIR/$tfile)
15460         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15461
15462         # Sleep for a while for statfs to get updated. And not pull from cache.
15463         sleep 2
15464
15465         echo "df after fallocate:"
15466         $LFS df
15467
15468         (( size / 1024 == space )) || error "size $size != requested $space"
15469         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15470                 error "used $used < space $space"
15471
15472         rm $DIR/$tfile || error "rm failed"
15473         sync
15474         wait_delete_completed
15475
15476         echo "df after unlink:"
15477         $LFS df
15478 }
15479 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15480
15481 test_150f() {
15482         local size
15483         local blocks
15484         local want_size_before=20480 # in bytes
15485         local want_blocks_before=40 # 512 sized blocks
15486         local want_blocks_after=24  # 512 sized blocks
15487         local length=$(((want_blocks_before - want_blocks_after) * 512))
15488
15489         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15490                 skip "need at least 2.14.0 for fallocate punch"
15491
15492         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15493                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15494         fi
15495
15496         check_set_fallocate_or_skip
15497         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15498
15499         [[ "x$DOM" == "xyes" ]] &&
15500                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15501
15502         echo "Verify fallocate punch: Range within the file range"
15503         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15504                 error "dd failed for bs 4096 and count 5"
15505
15506         # Call fallocate with punch range which is within the file range
15507         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15508                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15509         # client must see changes immediately after fallocate
15510         size=$(stat -c '%s' $DIR/$tfile)
15511         blocks=$(stat -c '%b' $DIR/$tfile)
15512
15513         # Verify punch worked.
15514         (( blocks == want_blocks_after )) ||
15515                 error "punch failed: blocks $blocks != $want_blocks_after"
15516
15517         (( size == want_size_before )) ||
15518                 error "punch failed: size $size != $want_size_before"
15519
15520         # Verify there is hole in file
15521         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15522         # precomputed md5sum
15523         local expect="4a9a834a2db02452929c0a348273b4aa"
15524
15525         cksum=($(md5sum $DIR/$tfile))
15526         [[ "${cksum[0]}" == "$expect" ]] ||
15527                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15528
15529         # Start second sub-case for fallocate punch.
15530         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15531         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15532                 error "dd failed for bs 4096 and count 5"
15533
15534         # Punch range less than block size will have no change in block count
15535         want_blocks_after=40  # 512 sized blocks
15536
15537         # Punch overlaps two blocks and less than blocksize
15538         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15539                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15540         size=$(stat -c '%s' $DIR/$tfile)
15541         blocks=$(stat -c '%b' $DIR/$tfile)
15542
15543         # Verify punch worked.
15544         (( blocks == want_blocks_after )) ||
15545                 error "punch failed: blocks $blocks != $want_blocks_after"
15546
15547         (( size == want_size_before )) ||
15548                 error "punch failed: size $size != $want_size_before"
15549
15550         # Verify if range is really zero'ed out. We expect Zeros.
15551         # precomputed md5sum
15552         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15553         cksum=($(md5sum $DIR/$tfile))
15554         [[ "${cksum[0]}" == "$expect" ]] ||
15555                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15556 }
15557 run_test 150f "Verify fallocate punch functionality"
15558
15559 test_150g() {
15560         local space
15561         local size
15562         local blocks
15563         local blocks_after
15564         local size_after
15565         local BS=4096 # Block size in bytes
15566
15567         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15568                 skip "need at least 2.14.0 for fallocate punch"
15569
15570         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15571                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15572         fi
15573
15574         check_set_fallocate_or_skip
15575         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15576
15577         if [[ "x$DOM" == "xyes" ]]; then
15578                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15579                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15580         else
15581                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15582                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15583         fi
15584
15585         # Get 100MB per OST of the available space to reduce run time
15586         # else 60% of the available space if we are running SLOW tests
15587         if [ $SLOW == "no" ]; then
15588                 space=$((1024 * 100 * OSTCOUNT))
15589         else
15590                 # Find OST with Minimum Size
15591                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15592                         sort -un | head -1)
15593                 echo "min size OST: $space"
15594                 space=$(((space * 60)/100 * OSTCOUNT))
15595         fi
15596         # space in 1k units, round to 4k blocks
15597         local blkcount=$((space * 1024 / $BS))
15598
15599         echo "Verify fallocate punch: Very large Range"
15600         fallocate -l${space}k $DIR/$tfile ||
15601                 error "fallocate ${space}k $DIR/$tfile failed"
15602         # write 1M at the end, start and in the middle
15603         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15604                 error "dd failed: bs $BS count 256"
15605         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15606                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15607         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15608                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15609
15610         # Gather stats.
15611         size=$(stat -c '%s' $DIR/$tfile)
15612
15613         # gather punch length.
15614         local punch_size=$((size - (BS * 2)))
15615
15616         echo "punch_size = $punch_size"
15617         echo "size - punch_size: $((size - punch_size))"
15618         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15619
15620         # Call fallocate to punch all except 2 blocks. We leave the
15621         # first and the last block
15622         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15623         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15624                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15625
15626         size_after=$(stat -c '%s' $DIR/$tfile)
15627         blocks_after=$(stat -c '%b' $DIR/$tfile)
15628
15629         # Verify punch worked.
15630         # Size should be kept
15631         (( size == size_after )) ||
15632                 error "punch failed: size $size != $size_after"
15633
15634         # two 4k data blocks to remain plus possible 1 extra extent block
15635         (( blocks_after <= ((BS / 512) * 3) )) ||
15636                 error "too many blocks remains: $blocks_after"
15637
15638         # Verify that file has hole between the first and the last blocks
15639         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15640         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15641
15642         echo "Hole at [$hole_start, $hole_end)"
15643         (( hole_start == BS )) ||
15644                 error "no hole at offset $BS after punch"
15645
15646         (( hole_end == BS + punch_size )) ||
15647                 error "data at offset $hole_end < $((BS + punch_size))"
15648 }
15649 run_test 150g "Verify fallocate punch on large range"
15650
15651 test_150h() {
15652         local file=$DIR/$tfile
15653         local size
15654
15655         check_set_fallocate_or_skip
15656         statx_supported || skip_env "Test must be statx() syscall supported"
15657
15658         # fallocate() does not update the size information on the MDT
15659         fallocate -l 16K $file || error "failed to fallocate $file"
15660         cancel_lru_locks $OSC
15661         # STATX with cached-always mode will not send glimpse RPCs to OST,
15662         # it uses the caching attrs on the client side as much as possible.
15663         size=$($STATX --cached=always -c %s $file)
15664         [ $size == 16384 ] ||
15665                 error "size after fallocate() is $size, expected 16384"
15666 }
15667 run_test 150h "Verify extend fallocate updates the file size"
15668
15669 #LU-2902 roc_hit was not able to read all values from lproc
15670 function roc_hit_init() {
15671         local list=$(comma_list $(osts_nodes))
15672         local dir=$DIR/$tdir-check
15673         local file=$dir/$tfile
15674         local BEFORE
15675         local AFTER
15676         local idx
15677
15678         test_mkdir $dir
15679         #use setstripe to do a write to every ost
15680         for i in $(seq 0 $((OSTCOUNT-1))); do
15681                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15682                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15683                 idx=$(printf %04x $i)
15684                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15685                         awk '$1 == "cache_access" {sum += $7}
15686                                 END { printf("%0.0f", sum) }')
15687
15688                 cancel_lru_locks osc
15689                 cat $file >/dev/null
15690
15691                 AFTER=$(get_osd_param $list *OST*$idx stats |
15692                         awk '$1 == "cache_access" {sum += $7}
15693                                 END { printf("%0.0f", sum) }')
15694
15695                 echo BEFORE:$BEFORE AFTER:$AFTER
15696                 if ! let "AFTER - BEFORE == 4"; then
15697                         rm -rf $dir
15698                         error "roc_hit is not safe to use"
15699                 fi
15700                 rm $file
15701         done
15702
15703         rm -rf $dir
15704 }
15705
15706 function roc_hit() {
15707         local list=$(comma_list $(osts_nodes))
15708         echo $(get_osd_param $list '' stats |
15709                 awk '$1 == "cache_hit" {sum += $7}
15710                         END { printf("%0.0f", sum) }')
15711 }
15712
15713 function set_cache() {
15714         local on=1
15715
15716         if [ "$2" == "off" ]; then
15717                 on=0;
15718         fi
15719         local list=$(comma_list $(osts_nodes))
15720         set_osd_param $list '' $1_cache_enable $on
15721
15722         cancel_lru_locks osc
15723 }
15724
15725 test_151() {
15726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15727         remote_ost_nodsh && skip "remote OST with nodsh"
15728
15729         local CPAGES=3
15730         local list=$(comma_list $(osts_nodes))
15731
15732         # check whether obdfilter is cache capable at all
15733         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15734                 skip "not cache-capable obdfilter"
15735         fi
15736
15737         # check cache is enabled on all obdfilters
15738         if get_osd_param $list '' read_cache_enable | grep 0; then
15739                 skip "oss cache is disabled"
15740         fi
15741
15742         set_osd_param $list '' writethrough_cache_enable 1
15743
15744         # check write cache is enabled on all obdfilters
15745         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15746                 skip "oss write cache is NOT enabled"
15747         fi
15748
15749         roc_hit_init
15750
15751         #define OBD_FAIL_OBD_NO_LRU  0x609
15752         do_nodes $list $LCTL set_param fail_loc=0x609
15753
15754         # pages should be in the case right after write
15755         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15756                 error "dd failed"
15757
15758         local BEFORE=$(roc_hit)
15759         cancel_lru_locks osc
15760         cat $DIR/$tfile >/dev/null
15761         local AFTER=$(roc_hit)
15762
15763         do_nodes $list $LCTL set_param fail_loc=0
15764
15765         if ! let "AFTER - BEFORE == CPAGES"; then
15766                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15767         fi
15768
15769         cancel_lru_locks osc
15770         # invalidates OST cache
15771         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15772         set_osd_param $list '' read_cache_enable 0
15773         cat $DIR/$tfile >/dev/null
15774
15775         # now data shouldn't be found in the cache
15776         BEFORE=$(roc_hit)
15777         cancel_lru_locks osc
15778         cat $DIR/$tfile >/dev/null
15779         AFTER=$(roc_hit)
15780         if let "AFTER - BEFORE != 0"; then
15781                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15782         fi
15783
15784         set_osd_param $list '' read_cache_enable 1
15785         rm -f $DIR/$tfile
15786 }
15787 run_test 151 "test cache on oss and controls ==============================="
15788
15789 test_152() {
15790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15791
15792         local TF="$TMP/$tfile"
15793
15794         # simulate ENOMEM during write
15795 #define OBD_FAIL_OST_NOMEM      0x226
15796         lctl set_param fail_loc=0x80000226
15797         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15798         cp $TF $DIR/$tfile
15799         sync || error "sync failed"
15800         lctl set_param fail_loc=0
15801
15802         # discard client's cache
15803         cancel_lru_locks osc
15804
15805         # simulate ENOMEM during read
15806         lctl set_param fail_loc=0x80000226
15807         cmp $TF $DIR/$tfile || error "cmp failed"
15808         lctl set_param fail_loc=0
15809
15810         rm -f $TF
15811 }
15812 run_test 152 "test read/write with enomem ============================"
15813
15814 test_153() {
15815         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15816 }
15817 run_test 153 "test if fdatasync does not crash ======================="
15818
15819 dot_lustre_fid_permission_check() {
15820         local fid=$1
15821         local ffid=$MOUNT/.lustre/fid/$fid
15822         local test_dir=$2
15823
15824         echo "stat fid $fid"
15825         stat $ffid || error "stat $ffid failed."
15826         echo "touch fid $fid"
15827         touch $ffid || error "touch $ffid failed."
15828         echo "write to fid $fid"
15829         cat /etc/hosts > $ffid || error "write $ffid failed."
15830         echo "read fid $fid"
15831         diff /etc/hosts $ffid || error "read $ffid failed."
15832         echo "append write to fid $fid"
15833         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15834         echo "rename fid $fid"
15835         mv $ffid $test_dir/$tfile.1 &&
15836                 error "rename $ffid to $tfile.1 should fail."
15837         touch $test_dir/$tfile.1
15838         mv $test_dir/$tfile.1 $ffid &&
15839                 error "rename $tfile.1 to $ffid should fail."
15840         rm -f $test_dir/$tfile.1
15841         echo "truncate fid $fid"
15842         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15843         echo "link fid $fid"
15844         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15845         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15846                 echo "setfacl fid $fid"
15847                 setfacl -R -m u:$USER0:rwx $ffid ||
15848                         error "setfacl $ffid failed"
15849                 echo "getfacl fid $fid"
15850                 getfacl $ffid || error "getfacl $ffid failed."
15851         fi
15852         echo "unlink fid $fid"
15853         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15854         echo "mknod fid $fid"
15855         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15856
15857         fid=[0xf00000400:0x1:0x0]
15858         ffid=$MOUNT/.lustre/fid/$fid
15859
15860         echo "stat non-exist fid $fid"
15861         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15862         echo "write to non-exist fid $fid"
15863         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15864         echo "link new fid $fid"
15865         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15866
15867         mkdir -p $test_dir/$tdir
15868         touch $test_dir/$tdir/$tfile
15869         fid=$($LFS path2fid $test_dir/$tdir)
15870         rc=$?
15871         [ $rc -ne 0 ] &&
15872                 error "error: could not get fid for $test_dir/$dir/$tfile."
15873
15874         ffid=$MOUNT/.lustre/fid/$fid
15875
15876         echo "ls $fid"
15877         ls $ffid || error "ls $ffid failed."
15878         echo "touch $fid/$tfile.1"
15879         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15880
15881         echo "touch $MOUNT/.lustre/fid/$tfile"
15882         touch $MOUNT/.lustre/fid/$tfile && \
15883                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15884
15885         echo "setxattr to $MOUNT/.lustre/fid"
15886         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15887
15888         echo "listxattr for $MOUNT/.lustre/fid"
15889         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15890
15891         echo "delxattr from $MOUNT/.lustre/fid"
15892         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15893
15894         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15895         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15896                 error "touch invalid fid should fail."
15897
15898         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15899         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15900                 error "touch non-normal fid should fail."
15901
15902         echo "rename $tdir to $MOUNT/.lustre/fid"
15903         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15904                 error "rename to $MOUNT/.lustre/fid should fail."
15905
15906         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15907         then            # LU-3547
15908                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15909                 local new_obf_mode=777
15910
15911                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15912                 chmod $new_obf_mode $DIR/.lustre/fid ||
15913                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15914
15915                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15916                 [ $obf_mode -eq $new_obf_mode ] ||
15917                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15918
15919                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15920                 chmod $old_obf_mode $DIR/.lustre/fid ||
15921                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15922         fi
15923
15924         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15925         fid=$($LFS path2fid $test_dir/$tfile-2)
15926
15927         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15928         then # LU-5424
15929                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15930                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15931                         error "create lov data thru .lustre failed"
15932         fi
15933         echo "cp /etc/passwd $test_dir/$tfile-2"
15934         cp /etc/passwd $test_dir/$tfile-2 ||
15935                 error "copy to $test_dir/$tfile-2 failed."
15936         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15937         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15938                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15939
15940         rm -rf $test_dir/tfile.lnk
15941         rm -rf $test_dir/$tfile-2
15942 }
15943
15944 test_154A() {
15945         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15946                 skip "Need MDS version at least 2.4.1"
15947
15948         local tf=$DIR/$tfile
15949         touch $tf
15950
15951         local fid=$($LFS path2fid $tf)
15952         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15953
15954         # check that we get the same pathname back
15955         local rootpath
15956         local found
15957         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15958                 echo "$rootpath $fid"
15959                 found=$($LFS fid2path $rootpath "$fid")
15960                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15961                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15962         done
15963
15964         # check wrong root path format
15965         rootpath=$MOUNT"_wrong"
15966         found=$($LFS fid2path $rootpath "$fid")
15967         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15968 }
15969 run_test 154A "lfs path2fid and fid2path basic checks"
15970
15971 test_154B() {
15972         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15973                 skip "Need MDS version at least 2.4.1"
15974
15975         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15976         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15977         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15978         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15979
15980         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15981         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15982
15983         # check that we get the same pathname
15984         echo "PFID: $PFID, name: $name"
15985         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15986         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15987         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15988                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15989
15990         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15991 }
15992 run_test 154B "verify the ll_decode_linkea tool"
15993
15994 test_154a() {
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15997         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15998                 skip "Need MDS version at least 2.2.51"
15999         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16000
16001         cp /etc/hosts $DIR/$tfile
16002
16003         fid=$($LFS path2fid $DIR/$tfile)
16004         rc=$?
16005         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16006
16007         dot_lustre_fid_permission_check "$fid" $DIR ||
16008                 error "dot lustre permission check $fid failed"
16009
16010         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16011
16012         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16013
16014         touch $MOUNT/.lustre/file &&
16015                 error "creation is not allowed under .lustre"
16016
16017         mkdir $MOUNT/.lustre/dir &&
16018                 error "mkdir is not allowed under .lustre"
16019
16020         rm -rf $DIR/$tfile
16021 }
16022 run_test 154a "Open-by-FID"
16023
16024 test_154b() {
16025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16026         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16028         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16029                 skip "Need MDS version at least 2.2.51"
16030
16031         local remote_dir=$DIR/$tdir/remote_dir
16032         local MDTIDX=1
16033         local rc=0
16034
16035         mkdir -p $DIR/$tdir
16036         $LFS mkdir -i $MDTIDX $remote_dir ||
16037                 error "create remote directory failed"
16038
16039         cp /etc/hosts $remote_dir/$tfile
16040
16041         fid=$($LFS path2fid $remote_dir/$tfile)
16042         rc=$?
16043         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16044
16045         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16046                 error "dot lustre permission check $fid failed"
16047         rm -rf $DIR/$tdir
16048 }
16049 run_test 154b "Open-by-FID for remote directory"
16050
16051 test_154c() {
16052         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16053                 skip "Need MDS version at least 2.4.1"
16054
16055         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16056         local FID1=$($LFS path2fid $DIR/$tfile.1)
16057         local FID2=$($LFS path2fid $DIR/$tfile.2)
16058         local FID3=$($LFS path2fid $DIR/$tfile.3)
16059
16060         local N=1
16061         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16062                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16063                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16064                 local want=FID$N
16065                 [ "$FID" = "${!want}" ] ||
16066                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16067                 N=$((N + 1))
16068         done
16069
16070         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16071         do
16072                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16073                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16074                 N=$((N + 1))
16075         done
16076 }
16077 run_test 154c "lfs path2fid and fid2path multiple arguments"
16078
16079 test_154d() {
16080         remote_mds_nodsh && skip "remote MDS with nodsh"
16081         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16082                 skip "Need MDS version at least 2.5.53"
16083
16084         if remote_mds; then
16085                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16086         else
16087                 nid="0@lo"
16088         fi
16089         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16090         local fd
16091         local cmd
16092
16093         rm -f $DIR/$tfile
16094         touch $DIR/$tfile
16095
16096         local fid=$($LFS path2fid $DIR/$tfile)
16097         # Open the file
16098         fd=$(free_fd)
16099         cmd="exec $fd<$DIR/$tfile"
16100         eval $cmd
16101         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16102         echo "$fid_list" | grep "$fid"
16103         rc=$?
16104
16105         cmd="exec $fd>/dev/null"
16106         eval $cmd
16107         if [ $rc -ne 0 ]; then
16108                 error "FID $fid not found in open files list $fid_list"
16109         fi
16110 }
16111 run_test 154d "Verify open file fid"
16112
16113 test_154e()
16114 {
16115         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16116                 skip "Need MDS version at least 2.6.50"
16117
16118         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16119                 error ".lustre returned by readdir"
16120         fi
16121 }
16122 run_test 154e ".lustre is not returned by readdir"
16123
16124 test_154f() {
16125         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16126
16127         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16128         mkdir_on_mdt0 $DIR/$tdir
16129         # test dirs inherit from its stripe
16130         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16131         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16132         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16133         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16134         touch $DIR/f
16135
16136         # get fid of parents
16137         local FID0=$($LFS path2fid $DIR/$tdir)
16138         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16139         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16140         local FID3=$($LFS path2fid $DIR)
16141
16142         # check that path2fid --parents returns expected <parent_fid>/name
16143         # 1) test for a directory (single parent)
16144         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16145         [ "$parent" == "$FID0/foo1" ] ||
16146                 error "expected parent: $FID0/foo1, got: $parent"
16147
16148         # 2) test for a file with nlink > 1 (multiple parents)
16149         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16150         echo "$parent" | grep -F "$FID1/$tfile" ||
16151                 error "$FID1/$tfile not returned in parent list"
16152         echo "$parent" | grep -F "$FID2/link" ||
16153                 error "$FID2/link not returned in parent list"
16154
16155         # 3) get parent by fid
16156         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16157         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16158         echo "$parent" | grep -F "$FID1/$tfile" ||
16159                 error "$FID1/$tfile not returned in parent list (by fid)"
16160         echo "$parent" | grep -F "$FID2/link" ||
16161                 error "$FID2/link not returned in parent list (by fid)"
16162
16163         # 4) test for entry in root directory
16164         parent=$($LFS path2fid --parents $DIR/f)
16165         echo "$parent" | grep -F "$FID3/f" ||
16166                 error "$FID3/f not returned in parent list"
16167
16168         # 5) test it on root directory
16169         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16170                 error "$MOUNT should not have parents"
16171
16172         # enable xattr caching and check that linkea is correctly updated
16173         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16174         save_lustre_params client "llite.*.xattr_cache" > $save
16175         lctl set_param llite.*.xattr_cache 1
16176
16177         # 6.1) linkea update on rename
16178         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16179
16180         # get parents by fid
16181         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16182         # foo1 should no longer be returned in parent list
16183         echo "$parent" | grep -F "$FID1" &&
16184                 error "$FID1 should no longer be in parent list"
16185         # the new path should appear
16186         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16187                 error "$FID2/$tfile.moved is not in parent list"
16188
16189         # 6.2) linkea update on unlink
16190         rm -f $DIR/$tdir/foo2/link
16191         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16192         # foo2/link should no longer be returned in parent list
16193         echo "$parent" | grep -F "$FID2/link" &&
16194                 error "$FID2/link should no longer be in parent list"
16195         true
16196
16197         rm -f $DIR/f
16198         restore_lustre_params < $save
16199         rm -f $save
16200 }
16201 run_test 154f "get parent fids by reading link ea"
16202
16203 test_154g()
16204 {
16205         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16206            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16207                 skip "Need MDS version at least 2.6.92"
16208
16209         mkdir_on_mdt0 $DIR/$tdir
16210         llapi_fid_test -d $DIR/$tdir
16211 }
16212 run_test 154g "various llapi FID tests"
16213
16214 test_155_small_load() {
16215     local temp=$TMP/$tfile
16216     local file=$DIR/$tfile
16217
16218     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16219         error "dd of=$temp bs=6096 count=1 failed"
16220     cp $temp $file
16221     cancel_lru_locks $OSC
16222     cmp $temp $file || error "$temp $file differ"
16223
16224     $TRUNCATE $temp 6000
16225     $TRUNCATE $file 6000
16226     cmp $temp $file || error "$temp $file differ (truncate1)"
16227
16228     echo "12345" >>$temp
16229     echo "12345" >>$file
16230     cmp $temp $file || error "$temp $file differ (append1)"
16231
16232     echo "12345" >>$temp
16233     echo "12345" >>$file
16234     cmp $temp $file || error "$temp $file differ (append2)"
16235
16236     rm -f $temp $file
16237     true
16238 }
16239
16240 test_155_big_load() {
16241         remote_ost_nodsh && skip "remote OST with nodsh"
16242
16243         local temp=$TMP/$tfile
16244         local file=$DIR/$tfile
16245
16246         free_min_max
16247         local cache_size=$(do_facet ost$((MAXI+1)) \
16248                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16249
16250         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16251         # pre-set value
16252         if [ -z "$cache_size" ]; then
16253                 cache_size=256
16254         fi
16255         local large_file_size=$((cache_size * 2))
16256
16257         echo "OSS cache size: $cache_size KB"
16258         echo "Large file size: $large_file_size KB"
16259
16260         [ $MAXV -le $large_file_size ] &&
16261                 skip_env "max available OST size needs > $large_file_size KB"
16262
16263         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16264
16265         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16266                 error "dd of=$temp bs=$large_file_size count=1k failed"
16267         cp $temp $file
16268         ls -lh $temp $file
16269         cancel_lru_locks osc
16270         cmp $temp $file || error "$temp $file differ"
16271
16272         rm -f $temp $file
16273         true
16274 }
16275
16276 save_writethrough() {
16277         local facets=$(get_facets OST)
16278
16279         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16280 }
16281
16282 test_155a() {
16283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16284
16285         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16286
16287         save_writethrough $p
16288
16289         set_cache read on
16290         set_cache writethrough on
16291         test_155_small_load
16292         restore_lustre_params < $p
16293         rm -f $p
16294 }
16295 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16296
16297 test_155b() {
16298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16299
16300         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16301
16302         save_writethrough $p
16303
16304         set_cache read on
16305         set_cache writethrough off
16306         test_155_small_load
16307         restore_lustre_params < $p
16308         rm -f $p
16309 }
16310 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16311
16312 test_155c() {
16313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16314
16315         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16316
16317         save_writethrough $p
16318
16319         set_cache read off
16320         set_cache writethrough on
16321         test_155_small_load
16322         restore_lustre_params < $p
16323         rm -f $p
16324 }
16325 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16326
16327 test_155d() {
16328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16329
16330         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16331
16332         save_writethrough $p
16333
16334         set_cache read off
16335         set_cache writethrough off
16336         test_155_small_load
16337         restore_lustre_params < $p
16338         rm -f $p
16339 }
16340 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16341
16342 test_155e() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344
16345         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16346
16347         save_writethrough $p
16348
16349         set_cache read on
16350         set_cache writethrough on
16351         test_155_big_load
16352         restore_lustre_params < $p
16353         rm -f $p
16354 }
16355 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16356
16357 test_155f() {
16358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16359
16360         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16361
16362         save_writethrough $p
16363
16364         set_cache read on
16365         set_cache writethrough off
16366         test_155_big_load
16367         restore_lustre_params < $p
16368         rm -f $p
16369 }
16370 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16371
16372 test_155g() {
16373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16374
16375         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16376
16377         save_writethrough $p
16378
16379         set_cache read off
16380         set_cache writethrough on
16381         test_155_big_load
16382         restore_lustre_params < $p
16383         rm -f $p
16384 }
16385 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16386
16387 test_155h() {
16388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16389
16390         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16391
16392         save_writethrough $p
16393
16394         set_cache read off
16395         set_cache writethrough off
16396         test_155_big_load
16397         restore_lustre_params < $p
16398         rm -f $p
16399 }
16400 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16401
16402 test_156() {
16403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16404         remote_ost_nodsh && skip "remote OST with nodsh"
16405         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16406                 skip "stats not implemented on old servers"
16407         [ "$ost1_FSTYPE" = "zfs" ] &&
16408                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16409
16410         local CPAGES=3
16411         local BEFORE
16412         local AFTER
16413         local file="$DIR/$tfile"
16414         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16415
16416         save_writethrough $p
16417         roc_hit_init
16418
16419         log "Turn on read and write cache"
16420         set_cache read on
16421         set_cache writethrough on
16422
16423         log "Write data and read it back."
16424         log "Read should be satisfied from the cache."
16425         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16426         BEFORE=$(roc_hit)
16427         cancel_lru_locks osc
16428         cat $file >/dev/null
16429         AFTER=$(roc_hit)
16430         if ! let "AFTER - BEFORE == CPAGES"; then
16431                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16432         else
16433                 log "cache hits: before: $BEFORE, after: $AFTER"
16434         fi
16435
16436         log "Read again; it should be satisfied from the cache."
16437         BEFORE=$AFTER
16438         cancel_lru_locks osc
16439         cat $file >/dev/null
16440         AFTER=$(roc_hit)
16441         if ! let "AFTER - BEFORE == CPAGES"; then
16442                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16443         else
16444                 log "cache hits:: before: $BEFORE, after: $AFTER"
16445         fi
16446
16447         log "Turn off the read cache and turn on the write cache"
16448         set_cache read off
16449         set_cache writethrough on
16450
16451         log "Read again; it should be satisfied from the cache."
16452         BEFORE=$(roc_hit)
16453         cancel_lru_locks osc
16454         cat $file >/dev/null
16455         AFTER=$(roc_hit)
16456         if ! let "AFTER - BEFORE == CPAGES"; then
16457                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16458         else
16459                 log "cache hits:: before: $BEFORE, after: $AFTER"
16460         fi
16461
16462         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16463                 # > 2.12.56 uses pagecache if cached
16464                 log "Read again; it should not be satisfied from the cache."
16465                 BEFORE=$AFTER
16466                 cancel_lru_locks osc
16467                 cat $file >/dev/null
16468                 AFTER=$(roc_hit)
16469                 if ! let "AFTER - BEFORE == 0"; then
16470                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16471                 else
16472                         log "cache hits:: before: $BEFORE, after: $AFTER"
16473                 fi
16474         fi
16475
16476         log "Write data and read it back."
16477         log "Read should be satisfied from the cache."
16478         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16479         BEFORE=$(roc_hit)
16480         cancel_lru_locks osc
16481         cat $file >/dev/null
16482         AFTER=$(roc_hit)
16483         if ! let "AFTER - BEFORE == CPAGES"; then
16484                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16485         else
16486                 log "cache hits:: before: $BEFORE, after: $AFTER"
16487         fi
16488
16489         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16490                 # > 2.12.56 uses pagecache if cached
16491                 log "Read again; it should not be satisfied from the cache."
16492                 BEFORE=$AFTER
16493                 cancel_lru_locks osc
16494                 cat $file >/dev/null
16495                 AFTER=$(roc_hit)
16496                 if ! let "AFTER - BEFORE == 0"; then
16497                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16498                 else
16499                         log "cache hits:: before: $BEFORE, after: $AFTER"
16500                 fi
16501         fi
16502
16503         log "Turn off read and write cache"
16504         set_cache read off
16505         set_cache writethrough off
16506
16507         log "Write data and read it back"
16508         log "It should not be satisfied from the cache."
16509         rm -f $file
16510         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16511         cancel_lru_locks osc
16512         BEFORE=$(roc_hit)
16513         cat $file >/dev/null
16514         AFTER=$(roc_hit)
16515         if ! let "AFTER - BEFORE == 0"; then
16516                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16517         else
16518                 log "cache hits:: before: $BEFORE, after: $AFTER"
16519         fi
16520
16521         log "Turn on the read cache and turn off the write cache"
16522         set_cache read on
16523         set_cache writethrough off
16524
16525         log "Write data and read it back"
16526         log "It should not be satisfied from the cache."
16527         rm -f $file
16528         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16529         BEFORE=$(roc_hit)
16530         cancel_lru_locks osc
16531         cat $file >/dev/null
16532         AFTER=$(roc_hit)
16533         if ! let "AFTER - BEFORE == 0"; then
16534                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16535         else
16536                 log "cache hits:: before: $BEFORE, after: $AFTER"
16537         fi
16538
16539         log "Read again; it should be satisfied from the cache."
16540         BEFORE=$(roc_hit)
16541         cancel_lru_locks osc
16542         cat $file >/dev/null
16543         AFTER=$(roc_hit)
16544         if ! let "AFTER - BEFORE == CPAGES"; then
16545                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16546         else
16547                 log "cache hits:: before: $BEFORE, after: $AFTER"
16548         fi
16549
16550         restore_lustre_params < $p
16551         rm -f $p $file
16552 }
16553 run_test 156 "Verification of tunables"
16554
16555 test_160a() {
16556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16557         remote_mds_nodsh && skip "remote MDS with nodsh"
16558         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16559                 skip "Need MDS version at least 2.2.0"
16560
16561         changelog_register || error "changelog_register failed"
16562         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16563         changelog_users $SINGLEMDS | grep -q $cl_user ||
16564                 error "User $cl_user not found in changelog_users"
16565
16566         mkdir_on_mdt0 $DIR/$tdir
16567
16568         # change something
16569         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16570         changelog_clear 0 || error "changelog_clear failed"
16571         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16572         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16573         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16574         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16575         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16576         rm $DIR/$tdir/pics/desktop.jpg
16577
16578         echo "verifying changelog mask"
16579         changelog_chmask "-MKDIR"
16580         changelog_chmask "-CLOSE"
16581
16582         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16583         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16584
16585         changelog_chmask "+MKDIR"
16586         changelog_chmask "+CLOSE"
16587
16588         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16589         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16590
16591         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16592         CLOSES=$(changelog_dump | grep -c "CLOSE")
16593         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16594         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16595
16596         # verify contents
16597         echo "verifying target fid"
16598         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16599         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16600         [ "$fidc" == "$fidf" ] ||
16601                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16602         echo "verifying parent fid"
16603         # The FID returned from the Changelog may be the directory shard on
16604         # a different MDT, and not the FID returned by path2fid on the parent.
16605         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16606         # since this is what will matter when recreating this file in the tree.
16607         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16608         local pathp=$($LFS fid2path $MOUNT "$fidp")
16609         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16610                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16611
16612         echo "getting records for $cl_user"
16613         changelog_users $SINGLEMDS
16614         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16615         local nclr=3
16616         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16617                 error "changelog_clear failed"
16618         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16619         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16620         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16621                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16622
16623         local min0_rec=$(changelog_users $SINGLEMDS |
16624                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16625         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16626                           awk '{ print $1; exit; }')
16627
16628         changelog_dump | tail -n 5
16629         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16630         [ $first_rec == $((min0_rec + 1)) ] ||
16631                 error "first index should be $min0_rec + 1 not $first_rec"
16632
16633         # LU-3446 changelog index reset on MDT restart
16634         local cur_rec1=$(changelog_users $SINGLEMDS |
16635                          awk '/^current.index:/ { print $NF }')
16636         changelog_clear 0 ||
16637                 error "clear all changelog records for $cl_user failed"
16638         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16639         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16640                 error "Fail to start $SINGLEMDS"
16641         local cur_rec2=$(changelog_users $SINGLEMDS |
16642                          awk '/^current.index:/ { print $NF }')
16643         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16644         [ $cur_rec1 == $cur_rec2 ] ||
16645                 error "current index should be $cur_rec1 not $cur_rec2"
16646
16647         echo "verifying users from this test are deregistered"
16648         changelog_deregister || error "changelog_deregister failed"
16649         changelog_users $SINGLEMDS | grep -q $cl_user &&
16650                 error "User '$cl_user' still in changelog_users"
16651
16652         # lctl get_param -n mdd.*.changelog_users
16653         # current_index: 144
16654         # ID    index (idle seconds)
16655         # cl3   144   (2) mask=<list>
16656         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16657                 # this is the normal case where all users were deregistered
16658                 # make sure no new records are added when no users are present
16659                 local last_rec1=$(changelog_users $SINGLEMDS |
16660                                   awk '/^current.index:/ { print $NF }')
16661                 touch $DIR/$tdir/chloe
16662                 local last_rec2=$(changelog_users $SINGLEMDS |
16663                                   awk '/^current.index:/ { print $NF }')
16664                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16665                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16666         else
16667                 # any changelog users must be leftovers from a previous test
16668                 changelog_users $SINGLEMDS
16669                 echo "other changelog users; can't verify off"
16670         fi
16671 }
16672 run_test 160a "changelog sanity"
16673
16674 test_160b() { # LU-3587
16675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16676         remote_mds_nodsh && skip "remote MDS with nodsh"
16677         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16678                 skip "Need MDS version at least 2.2.0"
16679
16680         changelog_register || error "changelog_register failed"
16681         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16682         changelog_users $SINGLEMDS | grep -q $cl_user ||
16683                 error "User '$cl_user' not found in changelog_users"
16684
16685         local longname1=$(str_repeat a 255)
16686         local longname2=$(str_repeat b 255)
16687
16688         cd $DIR
16689         echo "creating very long named file"
16690         touch $longname1 || error "create of '$longname1' failed"
16691         echo "renaming very long named file"
16692         mv $longname1 $longname2
16693
16694         changelog_dump | grep RENME | tail -n 5
16695         rm -f $longname2
16696 }
16697 run_test 160b "Verify that very long rename doesn't crash in changelog"
16698
16699 test_160c() {
16700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16701         remote_mds_nodsh && skip "remote MDS with nodsh"
16702
16703         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16704                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16705                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16706                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16707
16708         local rc=0
16709
16710         # Registration step
16711         changelog_register || error "changelog_register failed"
16712
16713         rm -rf $DIR/$tdir
16714         mkdir -p $DIR/$tdir
16715         $MCREATE $DIR/$tdir/foo_160c
16716         changelog_chmask "-TRUNC"
16717         $TRUNCATE $DIR/$tdir/foo_160c 200
16718         changelog_chmask "+TRUNC"
16719         $TRUNCATE $DIR/$tdir/foo_160c 199
16720         changelog_dump | tail -n 5
16721         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16722         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16723 }
16724 run_test 160c "verify that changelog log catch the truncate event"
16725
16726 test_160d() {
16727         remote_mds_nodsh && skip "remote MDS with nodsh"
16728         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16730         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16731                 skip "Need MDS version at least 2.7.60"
16732
16733         # Registration step
16734         changelog_register || error "changelog_register failed"
16735
16736         mkdir -p $DIR/$tdir/migrate_dir
16737         changelog_clear 0 || error "changelog_clear failed"
16738
16739         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16740         changelog_dump | tail -n 5
16741         local migrates=$(changelog_dump | grep -c "MIGRT")
16742         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16743 }
16744 run_test 160d "verify that changelog log catch the migrate event"
16745
16746 test_160e() {
16747         remote_mds_nodsh && skip "remote MDS with nodsh"
16748
16749         # Create a user
16750         changelog_register || error "changelog_register failed"
16751
16752         local MDT0=$(facet_svc $SINGLEMDS)
16753         local rc
16754
16755         # No user (expect fail)
16756         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16757         rc=$?
16758         if [ $rc -eq 0 ]; then
16759                 error "Should fail without user"
16760         elif [ $rc -ne 4 ]; then
16761                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16762         fi
16763
16764         # Delete a future user (expect fail)
16765         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16766         rc=$?
16767         if [ $rc -eq 0 ]; then
16768                 error "Deleted non-existant user cl77"
16769         elif [ $rc -ne 2 ]; then
16770                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16771         fi
16772
16773         # Clear to a bad index (1 billion should be safe)
16774         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16775         rc=$?
16776
16777         if [ $rc -eq 0 ]; then
16778                 error "Successfully cleared to invalid CL index"
16779         elif [ $rc -ne 22 ]; then
16780                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16781         fi
16782 }
16783 run_test 160e "changelog negative testing (should return errors)"
16784
16785 test_160f() {
16786         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16787         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16788                 skip "Need MDS version at least 2.10.56"
16789
16790         local mdts=$(comma_list $(mdts_nodes))
16791
16792         # Create a user
16793         changelog_register || error "first changelog_register failed"
16794         changelog_register || error "second changelog_register failed"
16795         local cl_users
16796         declare -A cl_user1
16797         declare -A cl_user2
16798         local user_rec1
16799         local user_rec2
16800         local i
16801
16802         # generate some changelog records to accumulate on each MDT
16803         # use all_char because created files should be evenly distributed
16804         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16805                 error "test_mkdir $tdir failed"
16806         log "$(date +%s): creating first files"
16807         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16808                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16809                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16810         done
16811
16812         # check changelogs have been generated
16813         local start=$SECONDS
16814         local idle_time=$((MDSCOUNT * 5 + 5))
16815         local nbcl=$(changelog_dump | wc -l)
16816         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16817
16818         for param in "changelog_max_idle_time=$idle_time" \
16819                      "changelog_gc=1" \
16820                      "changelog_min_gc_interval=2" \
16821                      "changelog_min_free_cat_entries=3"; do
16822                 local MDT0=$(facet_svc $SINGLEMDS)
16823                 local var="${param%=*}"
16824                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16825
16826                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16827                 do_nodes $mdts $LCTL set_param mdd.*.$param
16828         done
16829
16830         # force cl_user2 to be idle (1st part), but also cancel the
16831         # cl_user1 records so that it is not evicted later in the test.
16832         local sleep1=$((idle_time / 2))
16833         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16834         sleep $sleep1
16835
16836         # simulate changelog catalog almost full
16837         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16838         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16839
16840         for i in $(seq $MDSCOUNT); do
16841                 cl_users=(${CL_USERS[mds$i]})
16842                 cl_user1[mds$i]="${cl_users[0]}"
16843                 cl_user2[mds$i]="${cl_users[1]}"
16844
16845                 [ -n "${cl_user1[mds$i]}" ] ||
16846                         error "mds$i: no user registered"
16847                 [ -n "${cl_user2[mds$i]}" ] ||
16848                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16849
16850                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16851                 [ -n "$user_rec1" ] ||
16852                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16853                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16854                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16855                 [ -n "$user_rec2" ] ||
16856                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16857                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16858                      "$user_rec1 + 2 == $user_rec2"
16859                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16860                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16861                               "$user_rec1 + 2, but is $user_rec2"
16862                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16863                 [ -n "$user_rec2" ] ||
16864                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16865                 [ $user_rec1 == $user_rec2 ] ||
16866                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16867                               "$user_rec1, but is $user_rec2"
16868         done
16869
16870         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16871         local sleep2=$((idle_time - (SECONDS - start) + 1))
16872         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16873         sleep $sleep2
16874
16875         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16876         # cl_user1 should be OK because it recently processed records.
16877         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16878         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16879                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16880                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16881         done
16882
16883         # ensure gc thread is done
16884         for i in $(mdts_nodes); do
16885                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16886                         error "$i: GC-thread not done"
16887         done
16888
16889         local first_rec
16890         for (( i = 1; i <= MDSCOUNT; i++ )); do
16891                 # check cl_user1 still registered
16892                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16893                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16894                 # check cl_user2 unregistered
16895                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16896                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16897
16898                 # check changelogs are present and starting at $user_rec1 + 1
16899                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16900                 [ -n "$user_rec1" ] ||
16901                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16902                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16903                             awk '{ print $1; exit; }')
16904
16905                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16906                 [ $((user_rec1 + 1)) == $first_rec ] ||
16907                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16908         done
16909 }
16910 run_test 160f "changelog garbage collect (timestamped users)"
16911
16912 test_160g() {
16913         remote_mds_nodsh && skip "remote MDS with nodsh"
16914         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16915                 skip "Need MDS version at least 2.14.55"
16916
16917         local mdts=$(comma_list $(mdts_nodes))
16918
16919         # Create a user
16920         changelog_register || error "first changelog_register failed"
16921         changelog_register || error "second changelog_register failed"
16922         local cl_users
16923         declare -A cl_user1
16924         declare -A cl_user2
16925         local user_rec1
16926         local user_rec2
16927         local i
16928
16929         # generate some changelog records to accumulate on each MDT
16930         # use all_char because created files should be evenly distributed
16931         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16932                 error "test_mkdir $tdir failed"
16933         for ((i = 0; i < MDSCOUNT; i++)); do
16934                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16935                         error "create $DIR/$tdir/d$i.1 failed"
16936         done
16937
16938         # check changelogs have been generated
16939         local nbcl=$(changelog_dump | wc -l)
16940         (( $nbcl > 0 )) || error "no changelogs found"
16941
16942         # reduce the max_idle_indexes value to make sure we exceed it
16943         for param in "changelog_max_idle_indexes=2" \
16944                      "changelog_gc=1" \
16945                      "changelog_min_gc_interval=2"; do
16946                 local MDT0=$(facet_svc $SINGLEMDS)
16947                 local var="${param%=*}"
16948                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16949
16950                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16951                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16952                         error "unable to set mdd.*.$param"
16953         done
16954
16955         local start=$SECONDS
16956         for i in $(seq $MDSCOUNT); do
16957                 cl_users=(${CL_USERS[mds$i]})
16958                 cl_user1[mds$i]="${cl_users[0]}"
16959                 cl_user2[mds$i]="${cl_users[1]}"
16960
16961                 [ -n "${cl_user1[mds$i]}" ] ||
16962                         error "mds$i: user1 is not registered"
16963                 [ -n "${cl_user2[mds$i]}" ] ||
16964                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16965
16966                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16967                 [ -n "$user_rec1" ] ||
16968                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16969                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16970                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16971                 [ -n "$user_rec2" ] ||
16972                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16973                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16974                      "$user_rec1 + 2 == $user_rec2"
16975                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16976                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16977                               "expected $user_rec1 + 2, but is $user_rec2"
16978                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16979                 [ -n "$user_rec2" ] ||
16980                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16981                 [ $user_rec1 == $user_rec2 ] ||
16982                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16983                               "expected $user_rec1, but is $user_rec2"
16984         done
16985
16986         # ensure we are past the previous changelog_min_gc_interval set above
16987         local sleep2=$((start + 2 - SECONDS))
16988         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16989         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16990         # cl_user1 should be OK because it recently processed records.
16991         for ((i = 0; i < MDSCOUNT; i++)); do
16992                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16993                         error "create $DIR/$tdir/d$i.3 failed"
16994         done
16995
16996         # ensure gc thread is done
16997         for i in $(mdts_nodes); do
16998                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16999                         error "$i: GC-thread not done"
17000         done
17001
17002         local first_rec
17003         for (( i = 1; i <= MDSCOUNT; i++ )); do
17004                 # check cl_user1 still registered
17005                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17006                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17007                 # check cl_user2 unregistered
17008                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17009                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17010
17011                 # check changelogs are present and starting at $user_rec1 + 1
17012                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17013                 [ -n "$user_rec1" ] ||
17014                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17015                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17016                             awk '{ print $1; exit; }')
17017
17018                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17019                 [ $((user_rec1 + 1)) == $first_rec ] ||
17020                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17021         done
17022 }
17023 run_test 160g "changelog garbage collect on idle records"
17024
17025 test_160h() {
17026         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17027         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17028                 skip "Need MDS version at least 2.10.56"
17029
17030         local mdts=$(comma_list $(mdts_nodes))
17031
17032         # Create a user
17033         changelog_register || error "first changelog_register failed"
17034         changelog_register || error "second changelog_register failed"
17035         local cl_users
17036         declare -A cl_user1
17037         declare -A cl_user2
17038         local user_rec1
17039         local user_rec2
17040         local i
17041
17042         # generate some changelog records to accumulate on each MDT
17043         # use all_char because created files should be evenly distributed
17044         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17045                 error "test_mkdir $tdir failed"
17046         for ((i = 0; i < MDSCOUNT; i++)); do
17047                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17048                         error "create $DIR/$tdir/d$i.1 failed"
17049         done
17050
17051         # check changelogs have been generated
17052         local nbcl=$(changelog_dump | wc -l)
17053         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17054
17055         for param in "changelog_max_idle_time=10" \
17056                      "changelog_gc=1" \
17057                      "changelog_min_gc_interval=2"; do
17058                 local MDT0=$(facet_svc $SINGLEMDS)
17059                 local var="${param%=*}"
17060                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17061
17062                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17063                 do_nodes $mdts $LCTL set_param mdd.*.$param
17064         done
17065
17066         # force cl_user2 to be idle (1st part)
17067         sleep 9
17068
17069         for i in $(seq $MDSCOUNT); do
17070                 cl_users=(${CL_USERS[mds$i]})
17071                 cl_user1[mds$i]="${cl_users[0]}"
17072                 cl_user2[mds$i]="${cl_users[1]}"
17073
17074                 [ -n "${cl_user1[mds$i]}" ] ||
17075                         error "mds$i: no user registered"
17076                 [ -n "${cl_user2[mds$i]}" ] ||
17077                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17078
17079                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17080                 [ -n "$user_rec1" ] ||
17081                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17082                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17083                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17084                 [ -n "$user_rec2" ] ||
17085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17086                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17087                      "$user_rec1 + 2 == $user_rec2"
17088                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17089                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17090                               "$user_rec1 + 2, but is $user_rec2"
17091                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17092                 [ -n "$user_rec2" ] ||
17093                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17094                 [ $user_rec1 == $user_rec2 ] ||
17095                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17096                               "$user_rec1, but is $user_rec2"
17097         done
17098
17099         # force cl_user2 to be idle (2nd part) and to reach
17100         # changelog_max_idle_time
17101         sleep 2
17102
17103         # force each GC-thread start and block then
17104         # one per MDT/MDD, set fail_val accordingly
17105         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17106         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17107
17108         # generate more changelogs to trigger fail_loc
17109         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17110                 error "create $DIR/$tdir/${tfile}bis failed"
17111
17112         # stop MDT to stop GC-thread, should be done in back-ground as it will
17113         # block waiting for the thread to be released and exit
17114         declare -A stop_pids
17115         for i in $(seq $MDSCOUNT); do
17116                 stop mds$i &
17117                 stop_pids[mds$i]=$!
17118         done
17119
17120         for i in $(mdts_nodes); do
17121                 local facet
17122                 local nb=0
17123                 local facets=$(facets_up_on_host $i)
17124
17125                 for facet in ${facets//,/ }; do
17126                         if [[ $facet == mds* ]]; then
17127                                 nb=$((nb + 1))
17128                         fi
17129                 done
17130                 # ensure each MDS's gc threads are still present and all in "R"
17131                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17132                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17133                         error "$i: expected $nb GC-thread"
17134                 wait_update $i \
17135                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17136                         "R" 20 ||
17137                         error "$i: GC-thread not found in R-state"
17138                 # check umounts of each MDT on MDS have reached kthread_stop()
17139                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17140                         error "$i: expected $nb umount"
17141                 wait_update $i \
17142                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17143                         error "$i: umount not found in D-state"
17144         done
17145
17146         # release all GC-threads
17147         do_nodes $mdts $LCTL set_param fail_loc=0
17148
17149         # wait for MDT stop to complete
17150         for i in $(seq $MDSCOUNT); do
17151                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17152         done
17153
17154         # XXX
17155         # may try to check if any orphan changelog records are present
17156         # via ldiskfs/zfs and llog_reader...
17157
17158         # re-start/mount MDTs
17159         for i in $(seq $MDSCOUNT); do
17160                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17161                         error "Fail to start mds$i"
17162         done
17163
17164         local first_rec
17165         for i in $(seq $MDSCOUNT); do
17166                 # check cl_user1 still registered
17167                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17168                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17169                 # check cl_user2 unregistered
17170                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17171                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17172
17173                 # check changelogs are present and starting at $user_rec1 + 1
17174                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17175                 [ -n "$user_rec1" ] ||
17176                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17177                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17178                             awk '{ print $1; exit; }')
17179
17180                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17181                 [ $((user_rec1 + 1)) == $first_rec ] ||
17182                         error "mds$i: first index should be $user_rec1 + 1, " \
17183                               "but is $first_rec"
17184         done
17185 }
17186 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17187               "during mount"
17188
17189 test_160i() {
17190
17191         local mdts=$(comma_list $(mdts_nodes))
17192
17193         changelog_register || error "first changelog_register failed"
17194
17195         # generate some changelog records to accumulate on each MDT
17196         # use all_char because created files should be evenly distributed
17197         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17198                 error "test_mkdir $tdir failed"
17199         for ((i = 0; i < MDSCOUNT; i++)); do
17200                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17201                         error "create $DIR/$tdir/d$i.1 failed"
17202         done
17203
17204         # check changelogs have been generated
17205         local nbcl=$(changelog_dump | wc -l)
17206         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17207
17208         # simulate race between register and unregister
17209         # XXX as fail_loc is set per-MDS, with DNE configs the race
17210         # simulation will only occur for one MDT per MDS and for the
17211         # others the normal race scenario will take place
17212         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17213         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17214         do_nodes $mdts $LCTL set_param fail_val=1
17215
17216         # unregister 1st user
17217         changelog_deregister &
17218         local pid1=$!
17219         # wait some time for deregister work to reach race rdv
17220         sleep 2
17221         # register 2nd user
17222         changelog_register || error "2nd user register failed"
17223
17224         wait $pid1 || error "1st user deregister failed"
17225
17226         local i
17227         local last_rec
17228         declare -A LAST_REC
17229         for i in $(seq $MDSCOUNT); do
17230                 if changelog_users mds$i | grep "^cl"; then
17231                         # make sure new records are added with one user present
17232                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17233                                           awk '/^current.index:/ { print $NF }')
17234                 else
17235                         error "mds$i has no user registered"
17236                 fi
17237         done
17238
17239         # generate more changelog records to accumulate on each MDT
17240         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17241                 error "create $DIR/$tdir/${tfile}bis failed"
17242
17243         for i in $(seq $MDSCOUNT); do
17244                 last_rec=$(changelog_users $SINGLEMDS |
17245                            awk '/^current.index:/ { print $NF }')
17246                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17247                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17248                         error "changelogs are off on mds$i"
17249         done
17250 }
17251 run_test 160i "changelog user register/unregister race"
17252
17253 test_160j() {
17254         remote_mds_nodsh && skip "remote MDS with nodsh"
17255         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17256                 skip "Need MDS version at least 2.12.56"
17257
17258         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17259         stack_trap "umount $MOUNT2" EXIT
17260
17261         changelog_register || error "first changelog_register failed"
17262         stack_trap "changelog_deregister" EXIT
17263
17264         # generate some changelog
17265         # use all_char because created files should be evenly distributed
17266         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17267                 error "mkdir $tdir failed"
17268         for ((i = 0; i < MDSCOUNT; i++)); do
17269                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17270                         error "create $DIR/$tdir/d$i.1 failed"
17271         done
17272
17273         # open the changelog device
17274         exec 3>/dev/changelog-$FSNAME-MDT0000
17275         stack_trap "exec 3>&-" EXIT
17276         exec 4</dev/changelog-$FSNAME-MDT0000
17277         stack_trap "exec 4<&-" EXIT
17278
17279         # umount the first lustre mount
17280         umount $MOUNT
17281         stack_trap "mount_client $MOUNT" EXIT
17282
17283         # read changelog, which may or may not fail, but should not crash
17284         cat <&4 >/dev/null
17285
17286         # clear changelog
17287         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17288         changelog_users $SINGLEMDS | grep -q $cl_user ||
17289                 error "User $cl_user not found in changelog_users"
17290
17291         printf 'clear:'$cl_user':0' >&3
17292 }
17293 run_test 160j "client can be umounted while its chanangelog is being used"
17294
17295 test_160k() {
17296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17297         remote_mds_nodsh && skip "remote MDS with nodsh"
17298
17299         mkdir -p $DIR/$tdir/1/1
17300
17301         changelog_register || error "changelog_register failed"
17302         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17303
17304         changelog_users $SINGLEMDS | grep -q $cl_user ||
17305                 error "User '$cl_user' not found in changelog_users"
17306 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17307         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17308         rmdir $DIR/$tdir/1/1 & sleep 1
17309         mkdir $DIR/$tdir/2
17310         touch $DIR/$tdir/2/2
17311         rm -rf $DIR/$tdir/2
17312
17313         wait
17314         sleep 4
17315
17316         changelog_dump | grep rmdir || error "rmdir not recorded"
17317 }
17318 run_test 160k "Verify that changelog records are not lost"
17319
17320 # Verifies that a file passed as a parameter has recently had an operation
17321 # performed on it that has generated an MTIME changelog which contains the
17322 # correct parent FID. As files might reside on a different MDT from the
17323 # parent directory in DNE configurations, the FIDs are translated to paths
17324 # before being compared, which should be identical
17325 compare_mtime_changelog() {
17326         local file="${1}"
17327         local mdtidx
17328         local mtime
17329         local cl_fid
17330         local pdir
17331         local dir
17332
17333         mdtidx=$($LFS getstripe --mdt-index $file)
17334         mdtidx=$(printf "%04x" $mdtidx)
17335
17336         # Obtain the parent FID from the MTIME changelog
17337         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17338         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17339
17340         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17341         [ -z "$cl_fid" ] && error "parent FID not present"
17342
17343         # Verify that the path for the parent FID is the same as the path for
17344         # the test directory
17345         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17346
17347         dir=$(dirname $1)
17348
17349         [[ "${pdir%/}" == "$dir" ]] ||
17350                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17351 }
17352
17353 test_160l() {
17354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17355
17356         remote_mds_nodsh && skip "remote MDS with nodsh"
17357         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17358                 skip "Need MDS version at least 2.13.55"
17359
17360         local cl_user
17361
17362         changelog_register || error "changelog_register failed"
17363         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17364
17365         changelog_users $SINGLEMDS | grep -q $cl_user ||
17366                 error "User '$cl_user' not found in changelog_users"
17367
17368         # Clear some types so that MTIME changelogs are generated
17369         changelog_chmask "-CREAT"
17370         changelog_chmask "-CLOSE"
17371
17372         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17373
17374         # Test CL_MTIME during setattr
17375         touch $DIR/$tdir/$tfile
17376         compare_mtime_changelog $DIR/$tdir/$tfile
17377
17378         # Test CL_MTIME during close
17379         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17380         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17381 }
17382 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17383
17384 test_160m() {
17385         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17386         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17387                 skip "Need MDS version at least 2.14.51"
17388         local cl_users
17389         local cl_user1
17390         local cl_user2
17391         local pid1
17392
17393         # Create a user
17394         changelog_register || error "first changelog_register failed"
17395         changelog_register || error "second changelog_register failed"
17396
17397         cl_users=(${CL_USERS[mds1]})
17398         cl_user1="${cl_users[0]}"
17399         cl_user2="${cl_users[1]}"
17400         # generate some changelog records to accumulate on MDT0
17401         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17402         createmany -m $DIR/$tdir/$tfile 50 ||
17403                 error "create $DIR/$tdir/$tfile failed"
17404         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17405         rm -f $DIR/$tdir
17406
17407         # check changelogs have been generated
17408         local nbcl=$(changelog_dump | wc -l)
17409         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17410
17411 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17412         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17413
17414         __changelog_clear mds1 $cl_user1 +10
17415         __changelog_clear mds1 $cl_user2 0 &
17416         pid1=$!
17417         sleep 2
17418         __changelog_clear mds1 $cl_user1 0 ||
17419                 error "fail to cancel record for $cl_user1"
17420         wait $pid1
17421         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17422 }
17423 run_test 160m "Changelog clear race"
17424
17425 test_160n() {
17426         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17427         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17428                 skip "Need MDS version at least 2.14.51"
17429         local cl_users
17430         local cl_user1
17431         local cl_user2
17432         local pid1
17433         local first_rec
17434         local last_rec=0
17435
17436         # Create a user
17437         changelog_register || error "first changelog_register failed"
17438
17439         cl_users=(${CL_USERS[mds1]})
17440         cl_user1="${cl_users[0]}"
17441
17442         # generate some changelog records to accumulate on MDT0
17443         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17444         first_rec=$(changelog_users $SINGLEMDS |
17445                         awk '/^current.index:/ { print $NF }')
17446         while (( last_rec < (( first_rec + 65000)) )); do
17447                 createmany -m $DIR/$tdir/$tfile 10000 ||
17448                         error "create $DIR/$tdir/$tfile failed"
17449
17450                 for i in $(seq 0 10000); do
17451                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17452                                 > /dev/null
17453                 done
17454
17455                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17456                         error "unlinkmany failed unlink"
17457                 last_rec=$(changelog_users $SINGLEMDS |
17458                         awk '/^current.index:/ { print $NF }')
17459                 echo last record $last_rec
17460                 (( last_rec == 0 )) && error "no changelog found"
17461         done
17462
17463 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17464         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17465
17466         __changelog_clear mds1 $cl_user1 0 &
17467         pid1=$!
17468         sleep 2
17469         __changelog_clear mds1 $cl_user1 0 ||
17470                 error "fail to cancel record for $cl_user1"
17471         wait $pid1
17472         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17473 }
17474 run_test 160n "Changelog destroy race"
17475
17476 test_160o() {
17477         local mdt="$(facet_svc $SINGLEMDS)"
17478
17479         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17480         remote_mds_nodsh && skip "remote MDS with nodsh"
17481         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17482                 skip "Need MDS version at least 2.14.52"
17483
17484         changelog_register --user test_160o -m unlnk+close+open ||
17485                 error "changelog_register failed"
17486
17487         do_facet $SINGLEMDS $LCTL --device $mdt \
17488                                 changelog_register -u "Tt3_-#" &&
17489                 error "bad symbols in name should fail"
17490
17491         do_facet $SINGLEMDS $LCTL --device $mdt \
17492                                 changelog_register -u test_160o &&
17493                 error "the same name registration should fail"
17494
17495         do_facet $SINGLEMDS $LCTL --device $mdt \
17496                         changelog_register -u test_160toolongname &&
17497                 error "too long name registration should fail"
17498
17499         changelog_chmask "MARK+HSM"
17500         lctl get_param mdd.*.changelog*mask
17501         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17502         changelog_users $SINGLEMDS | grep -q $cl_user ||
17503                 error "User $cl_user not found in changelog_users"
17504         #verify username
17505         echo $cl_user | grep -q test_160o ||
17506                 error "User $cl_user has no specific name 'test160o'"
17507
17508         # change something
17509         changelog_clear 0 || error "changelog_clear failed"
17510         # generate some changelog records to accumulate on MDT0
17511         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17512         touch $DIR/$tdir/$tfile                 # open 1
17513
17514         OPENS=$(changelog_dump | grep -c "OPEN")
17515         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17516
17517         # must be no MKDIR it wasn't set as user mask
17518         MKDIR=$(changelog_dump | grep -c "MKDIR")
17519         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17520
17521         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17522                                 mdd.$mdt.changelog_current_mask -n)
17523         # register maskless user
17524         changelog_register || error "changelog_register failed"
17525         # effective mask should be not changed because it is not minimal
17526         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17527                                 mdd.$mdt.changelog_current_mask -n)
17528         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17529         # set server mask to minimal value
17530         changelog_chmask "MARK"
17531         # check effective mask again, should be treated as DEFMASK now
17532         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17533                                 mdd.$mdt.changelog_current_mask -n)
17534         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17535
17536         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17537                 # set server mask back to some value
17538                 changelog_chmask "CLOSE,UNLNK"
17539                 # check effective mask again, should not remain as DEFMASK
17540                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17541                                 mdd.$mdt.changelog_current_mask -n)
17542                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17543         fi
17544
17545         do_facet $SINGLEMDS $LCTL --device $mdt \
17546                                 changelog_deregister -u test_160o ||
17547                 error "cannot deregister by name"
17548 }
17549 run_test 160o "changelog user name and mask"
17550
17551 test_160p() {
17552         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17553         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17554                 skip "Need MDS version at least 2.14.51"
17555         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17556         local cl_users
17557         local cl_user1
17558         local entry_count
17559
17560         # Create a user
17561         changelog_register || error "first changelog_register failed"
17562
17563         cl_users=(${CL_USERS[mds1]})
17564         cl_user1="${cl_users[0]}"
17565
17566         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17567         createmany -m $DIR/$tdir/$tfile 50 ||
17568                 error "create $DIR/$tdir/$tfile failed"
17569         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17570         rm -rf $DIR/$tdir
17571
17572         # check changelogs have been generated
17573         entry_count=$(changelog_dump | wc -l)
17574         ((entry_count != 0)) || error "no changelog entries found"
17575
17576         # remove changelog_users and check that orphan entries are removed
17577         stop mds1
17578         local dev=$(mdsdevname 1)
17579         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17580         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17581         entry_count=$(changelog_dump | wc -l)
17582         ((entry_count == 0)) ||
17583                 error "found $entry_count changelog entries, expected none"
17584 }
17585 run_test 160p "Changelog orphan cleanup with no users"
17586
17587 test_160q() {
17588         local mdt="$(facet_svc $SINGLEMDS)"
17589         local clu
17590
17591         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17592         remote_mds_nodsh && skip "remote MDS with nodsh"
17593         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17594                 skip "Need MDS version at least 2.14.54"
17595
17596         # set server mask to minimal value like server init does
17597         changelog_chmask "MARK"
17598         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17599                 error "changelog_register failed"
17600         # check effective mask again, should be treated as DEFMASK now
17601         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17602                                 mdd.$mdt.changelog_current_mask -n)
17603         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17604                 error "changelog_deregister failed"
17605         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17606 }
17607 run_test 160q "changelog effective mask is DEFMASK if not set"
17608
17609 test_160s() {
17610         remote_mds_nodsh && skip "remote MDS with nodsh"
17611         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17612                 skip "Need MDS version at least 2.14.55"
17613
17614         local mdts=$(comma_list $(mdts_nodes))
17615
17616         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17617         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17618                                        fail_val=$((24 * 3600 * 10))
17619
17620         # Create a user which is 10 days old
17621         changelog_register || error "first changelog_register failed"
17622         local cl_users
17623         declare -A cl_user1
17624         local i
17625
17626         # generate some changelog records to accumulate on each MDT
17627         # use all_char because created files should be evenly distributed
17628         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17629                 error "test_mkdir $tdir failed"
17630         for ((i = 0; i < MDSCOUNT; i++)); do
17631                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17632                         error "create $DIR/$tdir/d$i.1 failed"
17633         done
17634
17635         # check changelogs have been generated
17636         local nbcl=$(changelog_dump | wc -l)
17637         (( nbcl > 0 )) || error "no changelogs found"
17638
17639         # reduce the max_idle_indexes value to make sure we exceed it
17640         for param in "changelog_max_idle_indexes=2097446912" \
17641                      "changelog_max_idle_time=2592000" \
17642                      "changelog_gc=1" \
17643                      "changelog_min_gc_interval=2"; do
17644                 local MDT0=$(facet_svc $SINGLEMDS)
17645                 local var="${param%=*}"
17646                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17647
17648                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17649                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17650                         error "unable to set mdd.*.$param"
17651         done
17652
17653         local start=$SECONDS
17654         for i in $(seq $MDSCOUNT); do
17655                 cl_users=(${CL_USERS[mds$i]})
17656                 cl_user1[mds$i]="${cl_users[0]}"
17657
17658                 [[ -n "${cl_user1[mds$i]}" ]] ||
17659                         error "mds$i: no user registered"
17660         done
17661
17662         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17663         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17664
17665         # ensure we are past the previous changelog_min_gc_interval set above
17666         local sleep2=$((start + 2 - SECONDS))
17667         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17668
17669         # Generate one more changelog to trigger GC
17670         for ((i = 0; i < MDSCOUNT; i++)); do
17671                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17672                         error "create $DIR/$tdir/d$i.3 failed"
17673         done
17674
17675         # ensure gc thread is done
17676         for node in $(mdts_nodes); do
17677                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17678                         error "$node: GC-thread not done"
17679         done
17680
17681         do_nodes $mdts $LCTL set_param fail_loc=0
17682
17683         for (( i = 1; i <= MDSCOUNT; i++ )); do
17684                 # check cl_user1 is purged
17685                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17686                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17687         done
17688         return 0
17689 }
17690 run_test 160s "changelog garbage collect on idle records * time"
17691
17692 test_160t() {
17693         remote_mds_nodsh && skip "remote MDS with nodsh"
17694         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17695                 skip "Need MDS version at least 2.15.50"
17696
17697         local MDT0=$(facet_svc $SINGLEMDS)
17698         local cl_users
17699         local cl_user1
17700         local cl_user2
17701         local start
17702
17703         changelog_register --user user1 -m all ||
17704                 error "user1 failed to register"
17705
17706         mkdir_on_mdt0 $DIR/$tdir
17707         # create default overstripe to maximize changelog size
17708         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17709         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17710         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17711
17712         # user2 consumes less records so less space
17713         changelog_register --user user2 || error "user2 failed to register"
17714         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17715         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17716
17717         # check changelogs have been generated
17718         local nbcl=$(changelog_dump | wc -l)
17719         (( nbcl > 0 )) || error "no changelogs found"
17720
17721         # reduce the changelog_min_gc_interval to force check
17722         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17723                 local var="${param%=*}"
17724                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17725
17726                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17727                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17728                         error "unable to set mdd.*.$param"
17729         done
17730
17731         start=$SECONDS
17732         cl_users=(${CL_USERS[mds1]})
17733         cl_user1="${cl_users[0]}"
17734         cl_user2="${cl_users[1]}"
17735
17736         [[ -n $cl_user1 ]] ||
17737                 error "mds1: user #1 isn't registered"
17738         [[ -n $cl_user2 ]] ||
17739                 error "mds1: user #2 isn't registered"
17740
17741         # ensure we are past the previous changelog_min_gc_interval set above
17742         local sleep2=$((start + 2 - SECONDS))
17743         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17744
17745         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17746         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17747                         fail_val=$(((llog_size1 + llog_size2) / 2))
17748
17749         # Generate more changelog to trigger GC
17750         createmany -o $DIR/$tdir/u3_ 4 ||
17751                 error "create failed for more files"
17752
17753         # ensure gc thread is done
17754         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17755                 error "mds1: GC-thread not done"
17756
17757         do_facet mds1 $LCTL set_param fail_loc=0
17758
17759         # check cl_user1 is purged
17760         changelog_users mds1 | grep -q "$cl_user1" &&
17761                 error "User $cl_user1 is registered"
17762         # check cl_user2 is not purged
17763         changelog_users mds1 | grep -q "$cl_user2" ||
17764                 error "User $cl_user2 is not registered"
17765 }
17766 run_test 160t "changelog garbage collect on lack of space"
17767
17768 test_161a() {
17769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17770
17771         test_mkdir -c1 $DIR/$tdir
17772         cp /etc/hosts $DIR/$tdir/$tfile
17773         test_mkdir -c1 $DIR/$tdir/foo1
17774         test_mkdir -c1 $DIR/$tdir/foo2
17775         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17776         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17777         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17778         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17779         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17780         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17781                 $LFS fid2path $DIR $FID
17782                 error "bad link ea"
17783         fi
17784         # middle
17785         rm $DIR/$tdir/foo2/zachary
17786         # last
17787         rm $DIR/$tdir/foo2/thor
17788         # first
17789         rm $DIR/$tdir/$tfile
17790         # rename
17791         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17792         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17793                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17794         rm $DIR/$tdir/foo2/maggie
17795
17796         # overflow the EA
17797         local longname=$tfile.avg_len_is_thirty_two_
17798         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17799                 error_noexit 'failed to unlink many hardlinks'" EXIT
17800         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17801                 error "failed to hardlink many files"
17802         links=$($LFS fid2path $DIR $FID | wc -l)
17803         echo -n "${links}/1000 links in link EA"
17804         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17805 }
17806 run_test 161a "link ea sanity"
17807
17808 test_161b() {
17809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17810         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17811
17812         local MDTIDX=1
17813         local remote_dir=$DIR/$tdir/remote_dir
17814
17815         mkdir -p $DIR/$tdir
17816         $LFS mkdir -i $MDTIDX $remote_dir ||
17817                 error "create remote directory failed"
17818
17819         cp /etc/hosts $remote_dir/$tfile
17820         mkdir -p $remote_dir/foo1
17821         mkdir -p $remote_dir/foo2
17822         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17823         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17824         ln $remote_dir/$tfile $remote_dir/foo1/luna
17825         ln $remote_dir/$tfile $remote_dir/foo2/thor
17826
17827         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17828                      tr -d ']')
17829         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17830                 $LFS fid2path $DIR $FID
17831                 error "bad link ea"
17832         fi
17833         # middle
17834         rm $remote_dir/foo2/zachary
17835         # last
17836         rm $remote_dir/foo2/thor
17837         # first
17838         rm $remote_dir/$tfile
17839         # rename
17840         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17841         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17842         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17843                 $LFS fid2path $DIR $FID
17844                 error "bad link rename"
17845         fi
17846         rm $remote_dir/foo2/maggie
17847
17848         # overflow the EA
17849         local longname=filename_avg_len_is_thirty_two_
17850         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17851                 error "failed to hardlink many files"
17852         links=$($LFS fid2path $DIR $FID | wc -l)
17853         echo -n "${links}/1000 links in link EA"
17854         [[ ${links} -gt 60 ]] ||
17855                 error "expected at least 60 links in link EA"
17856         unlinkmany $remote_dir/foo2/$longname 1000 ||
17857         error "failed to unlink many hardlinks"
17858 }
17859 run_test 161b "link ea sanity under remote directory"
17860
17861 test_161c() {
17862         remote_mds_nodsh && skip "remote MDS with nodsh"
17863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17864         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17865                 skip "Need MDS version at least 2.1.5"
17866
17867         # define CLF_RENAME_LAST 0x0001
17868         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17869         changelog_register || error "changelog_register failed"
17870
17871         rm -rf $DIR/$tdir
17872         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17873         touch $DIR/$tdir/foo_161c
17874         touch $DIR/$tdir/bar_161c
17875         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17876         changelog_dump | grep RENME | tail -n 5
17877         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17878         changelog_clear 0 || error "changelog_clear failed"
17879         if [ x$flags != "x0x1" ]; then
17880                 error "flag $flags is not 0x1"
17881         fi
17882
17883         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17884         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17885         touch $DIR/$tdir/foo_161c
17886         touch $DIR/$tdir/bar_161c
17887         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17888         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17889         changelog_dump | grep RENME | tail -n 5
17890         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17891         changelog_clear 0 || error "changelog_clear failed"
17892         if [ x$flags != "x0x0" ]; then
17893                 error "flag $flags is not 0x0"
17894         fi
17895         echo "rename overwrite a target having nlink > 1," \
17896                 "changelog record has flags of $flags"
17897
17898         # rename doesn't overwrite a target (changelog flag 0x0)
17899         touch $DIR/$tdir/foo_161c
17900         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17901         changelog_dump | grep RENME | tail -n 5
17902         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17903         changelog_clear 0 || error "changelog_clear failed"
17904         if [ x$flags != "x0x0" ]; then
17905                 error "flag $flags is not 0x0"
17906         fi
17907         echo "rename doesn't overwrite a target," \
17908                 "changelog record has flags of $flags"
17909
17910         # define CLF_UNLINK_LAST 0x0001
17911         # unlink a file having nlink = 1 (changelog flag 0x1)
17912         rm -f $DIR/$tdir/foo2_161c
17913         changelog_dump | grep UNLNK | tail -n 5
17914         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17915         changelog_clear 0 || error "changelog_clear failed"
17916         if [ x$flags != "x0x1" ]; then
17917                 error "flag $flags is not 0x1"
17918         fi
17919         echo "unlink a file having nlink = 1," \
17920                 "changelog record has flags of $flags"
17921
17922         # unlink a file having nlink > 1 (changelog flag 0x0)
17923         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17924         rm -f $DIR/$tdir/foobar_161c
17925         changelog_dump | grep UNLNK | tail -n 5
17926         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17927         changelog_clear 0 || error "changelog_clear failed"
17928         if [ x$flags != "x0x0" ]; then
17929                 error "flag $flags is not 0x0"
17930         fi
17931         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17932 }
17933 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17934
17935 test_161d() {
17936         remote_mds_nodsh && skip "remote MDS with nodsh"
17937         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17938
17939         local pid
17940         local fid
17941
17942         changelog_register || error "changelog_register failed"
17943
17944         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17945         # interfer with $MOUNT/.lustre/fid/ access
17946         mkdir $DIR/$tdir
17947         [[ $? -eq 0 ]] || error "mkdir failed"
17948
17949         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17950         $LCTL set_param fail_loc=0x8000140c
17951         # 5s pause
17952         $LCTL set_param fail_val=5
17953
17954         # create file
17955         echo foofoo > $DIR/$tdir/$tfile &
17956         pid=$!
17957
17958         # wait for create to be delayed
17959         sleep 2
17960
17961         ps -p $pid
17962         [[ $? -eq 0 ]] || error "create should be blocked"
17963
17964         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17965         stack_trap "rm -f $tempfile"
17966         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17967         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17968         # some delay may occur during ChangeLog publishing and file read just
17969         # above, that could allow file write to happen finally
17970         [[ -s $tempfile ]] && echo "file should be empty"
17971
17972         $LCTL set_param fail_loc=0
17973
17974         wait $pid
17975         [[ $? -eq 0 ]] || error "create failed"
17976 }
17977 run_test 161d "create with concurrent .lustre/fid access"
17978
17979 check_path() {
17980         local expected="$1"
17981         shift
17982         local fid="$2"
17983
17984         local path
17985         path=$($LFS fid2path "$@")
17986         local rc=$?
17987
17988         if [ $rc -ne 0 ]; then
17989                 error "path looked up of '$expected' failed: rc=$rc"
17990         elif [ "$path" != "$expected" ]; then
17991                 error "path looked up '$path' instead of '$expected'"
17992         else
17993                 echo "FID '$fid' resolves to path '$path' as expected"
17994         fi
17995 }
17996
17997 test_162a() { # was test_162
17998         test_mkdir -p -c1 $DIR/$tdir/d2
17999         touch $DIR/$tdir/d2/$tfile
18000         touch $DIR/$tdir/d2/x1
18001         touch $DIR/$tdir/d2/x2
18002         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18003         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18004         # regular file
18005         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18006         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18007
18008         # softlink
18009         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18010         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18011         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18012
18013         # softlink to wrong file
18014         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18015         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18016         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18017
18018         # hardlink
18019         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18020         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18021         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18022         # fid2path dir/fsname should both work
18023         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18024         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18025
18026         # hardlink count: check that there are 2 links
18027         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18028         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18029
18030         # hardlink indexing: remove the first link
18031         rm $DIR/$tdir/d2/p/q/r/hlink
18032         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18033 }
18034 run_test 162a "path lookup sanity"
18035
18036 test_162b() {
18037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18039
18040         mkdir $DIR/$tdir
18041         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18042                                 error "create striped dir failed"
18043
18044         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18045                                         tail -n 1 | awk '{print $2}')
18046         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18047
18048         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18049         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18050
18051         # regular file
18052         for ((i=0;i<5;i++)); do
18053                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18054                         error "get fid for f$i failed"
18055                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18056
18057                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18058                         error "get fid for d$i failed"
18059                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18060         done
18061
18062         return 0
18063 }
18064 run_test 162b "striped directory path lookup sanity"
18065
18066 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18067 test_162c() {
18068         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18069                 skip "Need MDS version at least 2.7.51"
18070
18071         local lpath=$tdir.local
18072         local rpath=$tdir.remote
18073
18074         test_mkdir $DIR/$lpath
18075         test_mkdir $DIR/$rpath
18076
18077         for ((i = 0; i <= 101; i++)); do
18078                 lpath="$lpath/$i"
18079                 mkdir $DIR/$lpath
18080                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18081                         error "get fid for local directory $DIR/$lpath failed"
18082                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18083
18084                 rpath="$rpath/$i"
18085                 test_mkdir $DIR/$rpath
18086                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18087                         error "get fid for remote directory $DIR/$rpath failed"
18088                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18089         done
18090
18091         return 0
18092 }
18093 run_test 162c "fid2path works with paths 100 or more directories deep"
18094
18095 oalr_event_count() {
18096         local event="${1}"
18097         local trace="${2}"
18098
18099         awk -v name="${FSNAME}-OST0000" \
18100             -v event="${event}" \
18101             '$1 == "TRACE" && $2 == event && $3 == name' \
18102             "${trace}" |
18103         wc -l
18104 }
18105
18106 oalr_expect_event_count() {
18107         local event="${1}"
18108         local trace="${2}"
18109         local expect="${3}"
18110         local count
18111
18112         count=$(oalr_event_count "${event}" "${trace}")
18113         if ((count == expect)); then
18114                 return 0
18115         fi
18116
18117         error_noexit "${event} event count was '${count}', expected ${expect}"
18118         cat "${trace}" >&2
18119         exit 1
18120 }
18121
18122 cleanup_165() {
18123         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18124         stop ost1
18125         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18126 }
18127
18128 setup_165() {
18129         sync # Flush previous IOs so we can count log entries.
18130         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18131         stack_trap cleanup_165 EXIT
18132 }
18133
18134 test_165a() {
18135         local trace="/tmp/${tfile}.trace"
18136         local rc
18137         local count
18138
18139         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18140                 skip "OFD access log unsupported"
18141
18142         setup_165
18143         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18144         sleep 5
18145
18146         do_facet ost1 ofd_access_log_reader --list
18147         stop ost1
18148
18149         do_facet ost1 killall -TERM ofd_access_log_reader
18150         wait
18151         rc=$?
18152
18153         if ((rc != 0)); then
18154                 error "ofd_access_log_reader exited with rc = '${rc}'"
18155         fi
18156
18157         # Parse trace file for discovery events:
18158         oalr_expect_event_count alr_log_add "${trace}" 1
18159         oalr_expect_event_count alr_log_eof "${trace}" 1
18160         oalr_expect_event_count alr_log_free "${trace}" 1
18161 }
18162 run_test 165a "ofd access log discovery"
18163
18164 test_165b() {
18165         local trace="/tmp/${tfile}.trace"
18166         local file="${DIR}/${tfile}"
18167         local pfid1
18168         local pfid2
18169         local -a entry
18170         local rc
18171         local count
18172         local size
18173         local flags
18174
18175         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18176                 skip "OFD access log unsupported"
18177
18178         setup_165
18179         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18180         sleep 5
18181
18182         do_facet ost1 ofd_access_log_reader --list
18183
18184         lfs setstripe -c 1 -i 0 "${file}"
18185         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18186                 error "cannot create '${file}'"
18187
18188         sleep 5
18189         do_facet ost1 killall -TERM ofd_access_log_reader
18190         wait
18191         rc=$?
18192
18193         if ((rc != 0)); then
18194                 error "ofd_access_log_reader exited with rc = '${rc}'"
18195         fi
18196
18197         oalr_expect_event_count alr_log_entry "${trace}" 1
18198
18199         pfid1=$($LFS path2fid "${file}")
18200
18201         # 1     2             3   4    5     6   7    8    9     10
18202         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18203         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18204
18205         echo "entry = '${entry[*]}'" >&2
18206
18207         pfid2=${entry[4]}
18208         if [[ "${pfid1}" != "${pfid2}" ]]; then
18209                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18210         fi
18211
18212         size=${entry[8]}
18213         if ((size != 1048576)); then
18214                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18215         fi
18216
18217         flags=${entry[10]}
18218         if [[ "${flags}" != "w" ]]; then
18219                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18220         fi
18221
18222         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18223         sleep 5
18224
18225         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18226                 error "cannot read '${file}'"
18227         sleep 5
18228
18229         do_facet ost1 killall -TERM ofd_access_log_reader
18230         wait
18231         rc=$?
18232
18233         if ((rc != 0)); then
18234                 error "ofd_access_log_reader exited with rc = '${rc}'"
18235         fi
18236
18237         oalr_expect_event_count alr_log_entry "${trace}" 1
18238
18239         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18240         echo "entry = '${entry[*]}'" >&2
18241
18242         pfid2=${entry[4]}
18243         if [[ "${pfid1}" != "${pfid2}" ]]; then
18244                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18245         fi
18246
18247         size=${entry[8]}
18248         if ((size != 524288)); then
18249                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18250         fi
18251
18252         flags=${entry[10]}
18253         if [[ "${flags}" != "r" ]]; then
18254                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18255         fi
18256 }
18257 run_test 165b "ofd access log entries are produced and consumed"
18258
18259 test_165c() {
18260         local trace="/tmp/${tfile}.trace"
18261         local file="${DIR}/${tdir}/${tfile}"
18262
18263         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18264                 skip "OFD access log unsupported"
18265
18266         test_mkdir "${DIR}/${tdir}"
18267
18268         setup_165
18269         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18270         sleep 5
18271
18272         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18273
18274         # 4096 / 64 = 64. Create twice as many entries.
18275         for ((i = 0; i < 128; i++)); do
18276                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18277                         error "cannot create file"
18278         done
18279
18280         sync
18281
18282         do_facet ost1 killall -TERM ofd_access_log_reader
18283         wait
18284         rc=$?
18285         if ((rc != 0)); then
18286                 error "ofd_access_log_reader exited with rc = '${rc}'"
18287         fi
18288
18289         unlinkmany  "${file}-%d" 128
18290 }
18291 run_test 165c "full ofd access logs do not block IOs"
18292
18293 oal_get_read_count() {
18294         local stats="$1"
18295
18296         # STATS lustre-OST0001 alr_read_count 1
18297
18298         do_facet ost1 cat "${stats}" |
18299         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18300              END { print count; }'
18301 }
18302
18303 oal_expect_read_count() {
18304         local stats="$1"
18305         local count
18306         local expect="$2"
18307
18308         # Ask ofd_access_log_reader to write stats.
18309         do_facet ost1 killall -USR1 ofd_access_log_reader
18310
18311         # Allow some time for things to happen.
18312         sleep 1
18313
18314         count=$(oal_get_read_count "${stats}")
18315         if ((count == expect)); then
18316                 return 0
18317         fi
18318
18319         error_noexit "bad read count, got ${count}, expected ${expect}"
18320         do_facet ost1 cat "${stats}" >&2
18321         exit 1
18322 }
18323
18324 test_165d() {
18325         local stats="/tmp/${tfile}.stats"
18326         local file="${DIR}/${tdir}/${tfile}"
18327         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18328
18329         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18330                 skip "OFD access log unsupported"
18331
18332         test_mkdir "${DIR}/${tdir}"
18333
18334         setup_165
18335         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18336         sleep 5
18337
18338         lfs setstripe -c 1 -i 0 "${file}"
18339
18340         do_facet ost1 lctl set_param "${param}=rw"
18341         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18342                 error "cannot create '${file}'"
18343         oal_expect_read_count "${stats}" 1
18344
18345         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18346                 error "cannot read '${file}'"
18347         oal_expect_read_count "${stats}" 2
18348
18349         do_facet ost1 lctl set_param "${param}=r"
18350         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18351                 error "cannot create '${file}'"
18352         oal_expect_read_count "${stats}" 2
18353
18354         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18355                 error "cannot read '${file}'"
18356         oal_expect_read_count "${stats}" 3
18357
18358         do_facet ost1 lctl set_param "${param}=w"
18359         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18360                 error "cannot create '${file}'"
18361         oal_expect_read_count "${stats}" 4
18362
18363         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18364                 error "cannot read '${file}'"
18365         oal_expect_read_count "${stats}" 4
18366
18367         do_facet ost1 lctl set_param "${param}=0"
18368         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18369                 error "cannot create '${file}'"
18370         oal_expect_read_count "${stats}" 4
18371
18372         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18373                 error "cannot read '${file}'"
18374         oal_expect_read_count "${stats}" 4
18375
18376         do_facet ost1 killall -TERM ofd_access_log_reader
18377         wait
18378         rc=$?
18379         if ((rc != 0)); then
18380                 error "ofd_access_log_reader exited with rc = '${rc}'"
18381         fi
18382 }
18383 run_test 165d "ofd_access_log mask works"
18384
18385 test_165e() {
18386         local stats="/tmp/${tfile}.stats"
18387         local file0="${DIR}/${tdir}-0/${tfile}"
18388         local file1="${DIR}/${tdir}-1/${tfile}"
18389
18390         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18391                 skip "OFD access log unsupported"
18392
18393         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18394
18395         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18396         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18397
18398         lfs setstripe -c 1 -i 0 "${file0}"
18399         lfs setstripe -c 1 -i 0 "${file1}"
18400
18401         setup_165
18402         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18403         sleep 5
18404
18405         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18406                 error "cannot create '${file0}'"
18407         sync
18408         oal_expect_read_count "${stats}" 0
18409
18410         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18411                 error "cannot create '${file1}'"
18412         sync
18413         oal_expect_read_count "${stats}" 1
18414
18415         do_facet ost1 killall -TERM ofd_access_log_reader
18416         wait
18417         rc=$?
18418         if ((rc != 0)); then
18419                 error "ofd_access_log_reader exited with rc = '${rc}'"
18420         fi
18421 }
18422 run_test 165e "ofd_access_log MDT index filter works"
18423
18424 test_165f() {
18425         local trace="/tmp/${tfile}.trace"
18426         local rc
18427         local count
18428
18429         setup_165
18430         do_facet ost1 timeout 60 ofd_access_log_reader \
18431                 --exit-on-close --debug=- --trace=- > "${trace}" &
18432         sleep 5
18433         stop ost1
18434
18435         wait
18436         rc=$?
18437
18438         if ((rc != 0)); then
18439                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18440                 cat "${trace}"
18441                 exit 1
18442         fi
18443 }
18444 run_test 165f "ofd_access_log_reader --exit-on-close works"
18445
18446 test_169() {
18447         # do directio so as not to populate the page cache
18448         log "creating a 10 Mb file"
18449         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18450                 error "multiop failed while creating a file"
18451         log "starting reads"
18452         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18453         log "truncating the file"
18454         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18455                 error "multiop failed while truncating the file"
18456         log "killing dd"
18457         kill %+ || true # reads might have finished
18458         echo "wait until dd is finished"
18459         wait
18460         log "removing the temporary file"
18461         rm -rf $DIR/$tfile || error "tmp file removal failed"
18462 }
18463 run_test 169 "parallel read and truncate should not deadlock"
18464
18465 test_170() {
18466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18467
18468         $LCTL clear     # bug 18514
18469         $LCTL debug_daemon start $TMP/${tfile}_log_good
18470         touch $DIR/$tfile
18471         $LCTL debug_daemon stop
18472         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18473                 error "sed failed to read log_good"
18474
18475         $LCTL debug_daemon start $TMP/${tfile}_log_good
18476         rm -rf $DIR/$tfile
18477         $LCTL debug_daemon stop
18478
18479         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18480                error "lctl df log_bad failed"
18481
18482         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18483         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18484
18485         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18486         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18487
18488         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18489                 error "bad_line good_line1 good_line2 are empty"
18490
18491         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18492         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18493         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18494
18495         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18496         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18497         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18498
18499         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18500                 error "bad_line_new good_line_new are empty"
18501
18502         local expected_good=$((good_line1 + good_line2*2))
18503
18504         rm -f $TMP/${tfile}*
18505         # LU-231, short malformed line may not be counted into bad lines
18506         if [ $bad_line -ne $bad_line_new ] &&
18507                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18508                 error "expected $bad_line bad lines, but got $bad_line_new"
18509                 return 1
18510         fi
18511
18512         if [ $expected_good -ne $good_line_new ]; then
18513                 error "expected $expected_good good lines, but got $good_line_new"
18514                 return 2
18515         fi
18516         true
18517 }
18518 run_test 170 "test lctl df to handle corrupted log ====================="
18519
18520 test_171() { # bug20592
18521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18522
18523         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18524         $LCTL set_param fail_loc=0x50e
18525         $LCTL set_param fail_val=3000
18526         multiop_bg_pause $DIR/$tfile O_s || true
18527         local MULTIPID=$!
18528         kill -USR1 $MULTIPID
18529         # cause log dump
18530         sleep 3
18531         wait $MULTIPID
18532         if dmesg | grep "recursive fault"; then
18533                 error "caught a recursive fault"
18534         fi
18535         $LCTL set_param fail_loc=0
18536         true
18537 }
18538 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18539
18540 test_172() {
18541
18542         #define OBD_FAIL_OBD_CLEANUP  0x60e
18543         $LCTL set_param fail_loc=0x60e
18544         umount $MOUNT || error "umount $MOUNT failed"
18545         stack_trap "mount_client $MOUNT"
18546
18547         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18548                 error "no client OBDs are remained"
18549
18550         $LCTL dl | while read devno state type name foo; do
18551                 case $type in
18552                 lov|osc|lmv|mdc)
18553                         $LCTL --device $name cleanup
18554                         $LCTL --device $name detach
18555                         ;;
18556                 *)
18557                         # skip server devices
18558                         ;;
18559                 esac
18560         done
18561
18562         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18563                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18564                 error "some client OBDs are still remained"
18565         fi
18566
18567 }
18568 run_test 172 "manual device removal with lctl cleanup/detach ======"
18569
18570 # it would be good to share it with obdfilter-survey/iokit-libecho code
18571 setup_obdecho_osc () {
18572         local rc=0
18573         local ost_nid=$1
18574         local obdfilter_name=$2
18575         echo "Creating new osc for $obdfilter_name on $ost_nid"
18576         # make sure we can find loopback nid
18577         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18578
18579         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18580                            ${obdfilter_name}_osc_UUID || rc=2; }
18581         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18582                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18583         return $rc
18584 }
18585
18586 cleanup_obdecho_osc () {
18587         local obdfilter_name=$1
18588         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18589         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18590         return 0
18591 }
18592
18593 obdecho_test() {
18594         local OBD=$1
18595         local node=$2
18596         local pages=${3:-64}
18597         local rc=0
18598         local id
18599
18600         local count=10
18601         local obd_size=$(get_obd_size $node $OBD)
18602         local page_size=$(get_page_size $node)
18603         if [[ -n "$obd_size" ]]; then
18604                 local new_count=$((obd_size / (pages * page_size / 1024)))
18605                 [[ $new_count -ge $count ]] || count=$new_count
18606         fi
18607
18608         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18609         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18610                            rc=2; }
18611         if [ $rc -eq 0 ]; then
18612             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18613             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18614         fi
18615         echo "New object id is $id"
18616         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18617                            rc=4; }
18618         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18619                            "test_brw $count w v $pages $id" || rc=4; }
18620         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18621                            rc=4; }
18622         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18623                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18624         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18625                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18626         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18627         return $rc
18628 }
18629
18630 test_180a() {
18631         skip "obdecho on osc is no longer supported"
18632 }
18633 run_test 180a "test obdecho on osc"
18634
18635 test_180b() {
18636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18637         remote_ost_nodsh && skip "remote OST with nodsh"
18638
18639         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18640                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18641                 error "failed to load module obdecho"
18642
18643         local target=$(do_facet ost1 $LCTL dl |
18644                        awk '/obdfilter/ { print $4; exit; }')
18645
18646         if [ -n "$target" ]; then
18647                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18648         else
18649                 do_facet ost1 $LCTL dl
18650                 error "there is no obdfilter target on ost1"
18651         fi
18652 }
18653 run_test 180b "test obdecho directly on obdfilter"
18654
18655 test_180c() { # LU-2598
18656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18657         remote_ost_nodsh && skip "remote OST with nodsh"
18658         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18659                 skip "Need MDS version at least 2.4.0"
18660
18661         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18662                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18663                 error "failed to load module obdecho"
18664
18665         local target=$(do_facet ost1 $LCTL dl |
18666                        awk '/obdfilter/ { print $4; exit; }')
18667
18668         if [ -n "$target" ]; then
18669                 local pages=16384 # 64MB bulk I/O RPC size
18670
18671                 obdecho_test "$target" ost1 "$pages" ||
18672                         error "obdecho_test with pages=$pages failed with $?"
18673         else
18674                 do_facet ost1 $LCTL dl
18675                 error "there is no obdfilter target on ost1"
18676         fi
18677 }
18678 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18679
18680 test_181() { # bug 22177
18681         test_mkdir $DIR/$tdir
18682         # create enough files to index the directory
18683         createmany -o $DIR/$tdir/foobar 4000
18684         # print attributes for debug purpose
18685         lsattr -d .
18686         # open dir
18687         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18688         MULTIPID=$!
18689         # remove the files & current working dir
18690         unlinkmany $DIR/$tdir/foobar 4000
18691         rmdir $DIR/$tdir
18692         kill -USR1 $MULTIPID
18693         wait $MULTIPID
18694         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18695         return 0
18696 }
18697 run_test 181 "Test open-unlinked dir ========================"
18698
18699 test_182a() {
18700         local fcount=1000
18701         local tcount=10
18702
18703         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18704
18705         $LCTL set_param mdc.*.rpc_stats=clear
18706
18707         for (( i = 0; i < $tcount; i++ )) ; do
18708                 mkdir $DIR/$tdir/$i
18709         done
18710
18711         for (( i = 0; i < $tcount; i++ )) ; do
18712                 createmany -o $DIR/$tdir/$i/f- $fcount &
18713         done
18714         wait
18715
18716         for (( i = 0; i < $tcount; i++ )) ; do
18717                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18718         done
18719         wait
18720
18721         $LCTL get_param mdc.*.rpc_stats
18722
18723         rm -rf $DIR/$tdir
18724 }
18725 run_test 182a "Test parallel modify metadata operations from mdc"
18726
18727 test_182b() {
18728         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18729         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18730         local dcount=1000
18731         local tcount=10
18732         local stime
18733         local etime
18734         local delta
18735
18736         do_facet mds1 $LCTL list_param \
18737                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18738                 skip "MDS lacks parallel RPC handling"
18739
18740         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18741
18742         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18743                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18744
18745         stime=$(date +%s)
18746         createmany -i 0 -d $DIR/$tdir/t- $tcount
18747
18748         for (( i = 0; i < $tcount; i++ )) ; do
18749                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18750         done
18751         wait
18752         etime=$(date +%s)
18753         delta=$((etime - stime))
18754         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18755
18756         stime=$(date +%s)
18757         for (( i = 0; i < $tcount; i++ )) ; do
18758                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18759         done
18760         wait
18761         etime=$(date +%s)
18762         delta=$((etime - stime))
18763         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18764
18765         rm -rf $DIR/$tdir
18766
18767         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18768
18769         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18770
18771         stime=$(date +%s)
18772         createmany -i 0 -d $DIR/$tdir/t- $tcount
18773
18774         for (( i = 0; i < $tcount; i++ )) ; do
18775                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18776         done
18777         wait
18778         etime=$(date +%s)
18779         delta=$((etime - stime))
18780         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18781
18782         stime=$(date +%s)
18783         for (( i = 0; i < $tcount; i++ )) ; do
18784                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18785         done
18786         wait
18787         etime=$(date +%s)
18788         delta=$((etime - stime))
18789         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18790
18791         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18792 }
18793 run_test 182b "Test parallel modify metadata operations from osp"
18794
18795 test_183() { # LU-2275
18796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18797         remote_mds_nodsh && skip "remote MDS with nodsh"
18798         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18799                 skip "Need MDS version at least 2.3.56"
18800
18801         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18802         echo aaa > $DIR/$tdir/$tfile
18803
18804 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18805         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18806
18807         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18808         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18809
18810         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18811
18812         # Flush negative dentry cache
18813         touch $DIR/$tdir/$tfile
18814
18815         # We are not checking for any leaked references here, they'll
18816         # become evident next time we do cleanup with module unload.
18817         rm -rf $DIR/$tdir
18818 }
18819 run_test 183 "No crash or request leak in case of strange dispositions ========"
18820
18821 # test suite 184 is for LU-2016, LU-2017
18822 test_184a() {
18823         check_swap_layouts_support
18824
18825         dir0=$DIR/$tdir/$testnum
18826         test_mkdir -p -c1 $dir0
18827         ref1=/etc/passwd
18828         ref2=/etc/group
18829         file1=$dir0/f1
18830         file2=$dir0/f2
18831         $LFS setstripe -c1 $file1
18832         cp $ref1 $file1
18833         $LFS setstripe -c2 $file2
18834         cp $ref2 $file2
18835         gen1=$($LFS getstripe -g $file1)
18836         gen2=$($LFS getstripe -g $file2)
18837
18838         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18839         gen=$($LFS getstripe -g $file1)
18840         [[ $gen1 != $gen ]] ||
18841                 error "Layout generation on $file1 does not change"
18842         gen=$($LFS getstripe -g $file2)
18843         [[ $gen2 != $gen ]] ||
18844                 error "Layout generation on $file2 does not change"
18845
18846         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18847         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18848
18849         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18850 }
18851 run_test 184a "Basic layout swap"
18852
18853 test_184b() {
18854         check_swap_layouts_support
18855
18856         dir0=$DIR/$tdir/$testnum
18857         mkdir -p $dir0 || error "creating dir $dir0"
18858         file1=$dir0/f1
18859         file2=$dir0/f2
18860         file3=$dir0/f3
18861         dir1=$dir0/d1
18862         dir2=$dir0/d2
18863         mkdir $dir1 $dir2
18864         $LFS setstripe -c1 $file1
18865         $LFS setstripe -c2 $file2
18866         $LFS setstripe -c1 $file3
18867         chown $RUNAS_ID $file3
18868         gen1=$($LFS getstripe -g $file1)
18869         gen2=$($LFS getstripe -g $file2)
18870
18871         $LFS swap_layouts $dir1 $dir2 &&
18872                 error "swap of directories layouts should fail"
18873         $LFS swap_layouts $dir1 $file1 &&
18874                 error "swap of directory and file layouts should fail"
18875         $RUNAS $LFS swap_layouts $file1 $file2 &&
18876                 error "swap of file we cannot write should fail"
18877         $LFS swap_layouts $file1 $file3 &&
18878                 error "swap of file with different owner should fail"
18879         /bin/true # to clear error code
18880 }
18881 run_test 184b "Forbidden layout swap (will generate errors)"
18882
18883 test_184c() {
18884         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18885         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18886         check_swap_layouts_support
18887         check_swap_layout_no_dom $DIR
18888
18889         local dir0=$DIR/$tdir/$testnum
18890         mkdir -p $dir0 || error "creating dir $dir0"
18891
18892         local ref1=$dir0/ref1
18893         local ref2=$dir0/ref2
18894         local file1=$dir0/file1
18895         local file2=$dir0/file2
18896         # create a file large enough for the concurrent test
18897         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18898         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18899         echo "ref file size: ref1($(stat -c %s $ref1))," \
18900              "ref2($(stat -c %s $ref2))"
18901
18902         cp $ref2 $file2
18903         dd if=$ref1 of=$file1 bs=16k &
18904         local DD_PID=$!
18905
18906         # Make sure dd starts to copy file, but wait at most 5 seconds
18907         local loops=0
18908         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18909
18910         $LFS swap_layouts $file1 $file2
18911         local rc=$?
18912         wait $DD_PID
18913         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18914         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18915
18916         # how many bytes copied before swapping layout
18917         local copied=$(stat -c %s $file2)
18918         local remaining=$(stat -c %s $ref1)
18919         remaining=$((remaining - copied))
18920         echo "Copied $copied bytes before swapping layout..."
18921
18922         cmp -n $copied $file1 $ref2 | grep differ &&
18923                 error "Content mismatch [0, $copied) of ref2 and file1"
18924         cmp -n $copied $file2 $ref1 ||
18925                 error "Content mismatch [0, $copied) of ref1 and file2"
18926         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18927                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18928
18929         # clean up
18930         rm -f $ref1 $ref2 $file1 $file2
18931 }
18932 run_test 184c "Concurrent write and layout swap"
18933
18934 test_184d() {
18935         check_swap_layouts_support
18936         check_swap_layout_no_dom $DIR
18937         [ -z "$(which getfattr 2>/dev/null)" ] &&
18938                 skip_env "no getfattr command"
18939
18940         local file1=$DIR/$tdir/$tfile-1
18941         local file2=$DIR/$tdir/$tfile-2
18942         local file3=$DIR/$tdir/$tfile-3
18943         local lovea1
18944         local lovea2
18945
18946         mkdir -p $DIR/$tdir
18947         touch $file1 || error "create $file1 failed"
18948         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18949                 error "create $file2 failed"
18950         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18951                 error "create $file3 failed"
18952         lovea1=$(get_layout_param $file1)
18953
18954         $LFS swap_layouts $file2 $file3 ||
18955                 error "swap $file2 $file3 layouts failed"
18956         $LFS swap_layouts $file1 $file2 ||
18957                 error "swap $file1 $file2 layouts failed"
18958
18959         lovea2=$(get_layout_param $file2)
18960         echo "$lovea1"
18961         echo "$lovea2"
18962         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18963
18964         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18965         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18966 }
18967 run_test 184d "allow stripeless layouts swap"
18968
18969 test_184e() {
18970         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18971                 skip "Need MDS version at least 2.6.94"
18972         check_swap_layouts_support
18973         check_swap_layout_no_dom $DIR
18974         [ -z "$(which getfattr 2>/dev/null)" ] &&
18975                 skip_env "no getfattr command"
18976
18977         local file1=$DIR/$tdir/$tfile-1
18978         local file2=$DIR/$tdir/$tfile-2
18979         local file3=$DIR/$tdir/$tfile-3
18980         local lovea
18981
18982         mkdir -p $DIR/$tdir
18983         touch $file1 || error "create $file1 failed"
18984         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18985                 error "create $file2 failed"
18986         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18987                 error "create $file3 failed"
18988
18989         $LFS swap_layouts $file1 $file2 ||
18990                 error "swap $file1 $file2 layouts failed"
18991
18992         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18993         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18994
18995         echo 123 > $file1 || error "Should be able to write into $file1"
18996
18997         $LFS swap_layouts $file1 $file3 ||
18998                 error "swap $file1 $file3 layouts failed"
18999
19000         echo 123 > $file1 || error "Should be able to write into $file1"
19001
19002         rm -rf $file1 $file2 $file3
19003 }
19004 run_test 184e "Recreate layout after stripeless layout swaps"
19005
19006 test_184f() {
19007         # Create a file with name longer than sizeof(struct stat) ==
19008         # 144 to see if we can get chars from the file name to appear
19009         # in the returned striping. Note that 'f' == 0x66.
19010         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19011
19012         mkdir -p $DIR/$tdir
19013         mcreate $DIR/$tdir/$file
19014         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19015                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19016         fi
19017 }
19018 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19019
19020 test_185() { # LU-2441
19021         # LU-3553 - no volatile file support in old servers
19022         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19023                 skip "Need MDS version at least 2.3.60"
19024
19025         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19026         touch $DIR/$tdir/spoo
19027         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19028         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19029                 error "cannot create/write a volatile file"
19030         [ "$FILESET" == "" ] &&
19031         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19032                 error "FID is still valid after close"
19033
19034         multiop_bg_pause $DIR/$tdir vVw4096_c
19035         local multi_pid=$!
19036
19037         local OLD_IFS=$IFS
19038         IFS=":"
19039         local fidv=($fid)
19040         IFS=$OLD_IFS
19041         # assume that the next FID for this client is sequential, since stdout
19042         # is unfortunately eaten by multiop_bg_pause
19043         local n=$((${fidv[1]} + 1))
19044         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19045         if [ "$FILESET" == "" ]; then
19046                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19047                         error "FID is missing before close"
19048         fi
19049         kill -USR1 $multi_pid
19050         # 1 second delay, so if mtime change we will see it
19051         sleep 1
19052         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19053         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19054 }
19055 run_test 185 "Volatile file support"
19056
19057 function create_check_volatile() {
19058         local idx=$1
19059         local tgt
19060
19061         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19062         local PID=$!
19063         sleep 1
19064         local FID=$(cat /tmp/${tfile}.fid)
19065         [ "$FID" == "" ] && error "can't get FID for volatile"
19066         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19067         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19068         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19069         kill -USR1 $PID
19070         wait
19071         sleep 1
19072         cancel_lru_locks mdc # flush opencache
19073         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19074         return 0
19075 }
19076
19077 test_185a(){
19078         # LU-12516 - volatile creation via .lustre
19079         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19080                 skip "Need MDS version at least 2.3.55"
19081
19082         create_check_volatile 0
19083         [ $MDSCOUNT -lt 2 ] && return 0
19084
19085         # DNE case
19086         create_check_volatile 1
19087
19088         return 0
19089 }
19090 run_test 185a "Volatile file creation in .lustre/fid/"
19091
19092 test_187a() {
19093         remote_mds_nodsh && skip "remote MDS with nodsh"
19094         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19095                 skip "Need MDS version at least 2.3.0"
19096
19097         local dir0=$DIR/$tdir/$testnum
19098         mkdir -p $dir0 || error "creating dir $dir0"
19099
19100         local file=$dir0/file1
19101         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19102         local dv1=$($LFS data_version $file)
19103         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19104         local dv2=$($LFS data_version $file)
19105         [[ $dv1 != $dv2 ]] ||
19106                 error "data version did not change on write $dv1 == $dv2"
19107
19108         # clean up
19109         rm -f $file1
19110 }
19111 run_test 187a "Test data version change"
19112
19113 test_187b() {
19114         remote_mds_nodsh && skip "remote MDS with nodsh"
19115         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19116                 skip "Need MDS version at least 2.3.0"
19117
19118         local dir0=$DIR/$tdir/$testnum
19119         mkdir -p $dir0 || error "creating dir $dir0"
19120
19121         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19122         [[ ${DV[0]} != ${DV[1]} ]] ||
19123                 error "data version did not change on write"\
19124                       " ${DV[0]} == ${DV[1]}"
19125
19126         # clean up
19127         rm -f $file1
19128 }
19129 run_test 187b "Test data version change on volatile file"
19130
19131 test_200() {
19132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19133         remote_mgs_nodsh && skip "remote MGS with nodsh"
19134         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19135
19136         local POOL=${POOL:-cea1}
19137         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19138         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19139         # Pool OST targets
19140         local first_ost=0
19141         local last_ost=$(($OSTCOUNT - 1))
19142         local ost_step=2
19143         local ost_list=$(seq $first_ost $ost_step $last_ost)
19144         local ost_range="$first_ost $last_ost $ost_step"
19145         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19146         local file_dir=$POOL_ROOT/file_tst
19147         local subdir=$test_path/subdir
19148         local rc=0
19149
19150         while : ; do
19151                 # former test_200a test_200b
19152                 pool_add $POOL                          || { rc=$? ; break; }
19153                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19154                 # former test_200c test_200d
19155                 mkdir -p $test_path
19156                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19157                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19158                 mkdir -p $subdir
19159                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19160                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19161                                                         || { rc=$? ; break; }
19162                 # former test_200e test_200f
19163                 local files=$((OSTCOUNT*3))
19164                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19165                                                         || { rc=$? ; break; }
19166                 pool_create_files $POOL $file_dir $files "$ost_list" \
19167                                                         || { rc=$? ; break; }
19168                 # former test_200g test_200h
19169                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19170                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19171
19172                 # former test_201a test_201b test_201c
19173                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19174
19175                 local f=$test_path/$tfile
19176                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19177                 pool_remove $POOL $f                    || { rc=$? ; break; }
19178                 break
19179         done
19180
19181         destroy_test_pools
19182
19183         return $rc
19184 }
19185 run_test 200 "OST pools"
19186
19187 # usage: default_attr <count | size | offset>
19188 default_attr() {
19189         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19190 }
19191
19192 # usage: check_default_stripe_attr
19193 check_default_stripe_attr() {
19194         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19195         case $1 in
19196         --stripe-count|-c)
19197                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19198         --stripe-size|-S)
19199                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19200         --stripe-index|-i)
19201                 EXPECTED=-1;;
19202         *)
19203                 error "unknown getstripe attr '$1'"
19204         esac
19205
19206         [ $ACTUAL == $EXPECTED ] ||
19207                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19208 }
19209
19210 test_204a() {
19211         test_mkdir $DIR/$tdir
19212         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19213
19214         check_default_stripe_attr --stripe-count
19215         check_default_stripe_attr --stripe-size
19216         check_default_stripe_attr --stripe-index
19217 }
19218 run_test 204a "Print default stripe attributes"
19219
19220 test_204b() {
19221         test_mkdir $DIR/$tdir
19222         $LFS setstripe --stripe-count 1 $DIR/$tdir
19223
19224         check_default_stripe_attr --stripe-size
19225         check_default_stripe_attr --stripe-index
19226 }
19227 run_test 204b "Print default stripe size and offset"
19228
19229 test_204c() {
19230         test_mkdir $DIR/$tdir
19231         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19232
19233         check_default_stripe_attr --stripe-count
19234         check_default_stripe_attr --stripe-index
19235 }
19236 run_test 204c "Print default stripe count and offset"
19237
19238 test_204d() {
19239         test_mkdir $DIR/$tdir
19240         $LFS setstripe --stripe-index 0 $DIR/$tdir
19241
19242         check_default_stripe_attr --stripe-count
19243         check_default_stripe_attr --stripe-size
19244 }
19245 run_test 204d "Print default stripe count and size"
19246
19247 test_204e() {
19248         test_mkdir $DIR/$tdir
19249         $LFS setstripe -d $DIR/$tdir
19250
19251         check_default_stripe_attr --stripe-count --raw
19252         check_default_stripe_attr --stripe-size --raw
19253         check_default_stripe_attr --stripe-index --raw
19254 }
19255 run_test 204e "Print raw stripe attributes"
19256
19257 test_204f() {
19258         test_mkdir $DIR/$tdir
19259         $LFS setstripe --stripe-count 1 $DIR/$tdir
19260
19261         check_default_stripe_attr --stripe-size --raw
19262         check_default_stripe_attr --stripe-index --raw
19263 }
19264 run_test 204f "Print raw stripe size and offset"
19265
19266 test_204g() {
19267         test_mkdir $DIR/$tdir
19268         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19269
19270         check_default_stripe_attr --stripe-count --raw
19271         check_default_stripe_attr --stripe-index --raw
19272 }
19273 run_test 204g "Print raw stripe count and offset"
19274
19275 test_204h() {
19276         test_mkdir $DIR/$tdir
19277         $LFS setstripe --stripe-index 0 $DIR/$tdir
19278
19279         check_default_stripe_attr --stripe-count --raw
19280         check_default_stripe_attr --stripe-size --raw
19281 }
19282 run_test 204h "Print raw stripe count and size"
19283
19284 # Figure out which job scheduler is being used, if any,
19285 # or use a fake one
19286 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19287         JOBENV=SLURM_JOB_ID
19288 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19289         JOBENV=LSB_JOBID
19290 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19291         JOBENV=PBS_JOBID
19292 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19293         JOBENV=LOADL_STEP_ID
19294 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19295         JOBENV=JOB_ID
19296 else
19297         $LCTL list_param jobid_name > /dev/null 2>&1
19298         if [ $? -eq 0 ]; then
19299                 JOBENV=nodelocal
19300         else
19301                 JOBENV=FAKE_JOBID
19302         fi
19303 fi
19304 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19305
19306 verify_jobstats() {
19307         local cmd=($1)
19308         shift
19309         local facets="$@"
19310
19311 # we don't really need to clear the stats for this test to work, since each
19312 # command has a unique jobid, but it makes debugging easier if needed.
19313 #       for facet in $facets; do
19314 #               local dev=$(convert_facet2label $facet)
19315 #               # clear old jobstats
19316 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19317 #       done
19318
19319         # use a new JobID for each test, or we might see an old one
19320         [ "$JOBENV" = "FAKE_JOBID" ] &&
19321                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19322
19323         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19324
19325         [ "$JOBENV" = "nodelocal" ] && {
19326                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19327                 $LCTL set_param jobid_name=$FAKE_JOBID
19328                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19329         }
19330
19331         log "Test: ${cmd[*]}"
19332         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19333
19334         if [ $JOBENV = "FAKE_JOBID" ]; then
19335                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19336         else
19337                 ${cmd[*]}
19338         fi
19339
19340         # all files are created on OST0000
19341         for facet in $facets; do
19342                 local stats="*.$(convert_facet2label $facet).job_stats"
19343
19344                 # strip out libtool wrappers for in-tree executables
19345                 if (( $(do_facet $facet lctl get_param $stats |
19346                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19347                         do_facet $facet lctl get_param $stats
19348                         error "No jobstats for $JOBVAL found on $facet::$stats"
19349                 fi
19350         done
19351 }
19352
19353 jobstats_set() {
19354         local new_jobenv=$1
19355
19356         set_persistent_param_and_check client "jobid_var" \
19357                 "$FSNAME.sys.jobid_var" $new_jobenv
19358 }
19359
19360 test_205a() { # Job stats
19361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19362         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19363                 skip "Need MDS version with at least 2.7.1"
19364         remote_mgs_nodsh && skip "remote MGS with nodsh"
19365         remote_mds_nodsh && skip "remote MDS with nodsh"
19366         remote_ost_nodsh && skip "remote OST with nodsh"
19367         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19368                 skip "Server doesn't support jobstats"
19369         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19370
19371         local old_jobenv=$($LCTL get_param -n jobid_var)
19372         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19373
19374         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19375                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19376         else
19377                 stack_trap "do_facet mgs $PERM_CMD \
19378                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19379         fi
19380         changelog_register
19381
19382         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19383                                 mdt.*.job_cleanup_interval | head -n 1)
19384         local new_interval=5
19385         do_facet $SINGLEMDS \
19386                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19387         stack_trap "do_facet $SINGLEMDS \
19388                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19389         local start=$SECONDS
19390
19391         local cmd
19392         # mkdir
19393         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19394         verify_jobstats "$cmd" "$SINGLEMDS"
19395         # rmdir
19396         cmd="rmdir $DIR/$tdir"
19397         verify_jobstats "$cmd" "$SINGLEMDS"
19398         # mkdir on secondary MDT
19399         if [ $MDSCOUNT -gt 1 ]; then
19400                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19401                 verify_jobstats "$cmd" "mds2"
19402         fi
19403         # mknod
19404         cmd="mknod $DIR/$tfile c 1 3"
19405         verify_jobstats "$cmd" "$SINGLEMDS"
19406         # unlink
19407         cmd="rm -f $DIR/$tfile"
19408         verify_jobstats "$cmd" "$SINGLEMDS"
19409         # create all files on OST0000 so verify_jobstats can find OST stats
19410         # open & close
19411         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19412         verify_jobstats "$cmd" "$SINGLEMDS"
19413         # setattr
19414         cmd="touch $DIR/$tfile"
19415         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19416         # write
19417         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19418         verify_jobstats "$cmd" "ost1"
19419         # read
19420         cancel_lru_locks osc
19421         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19422         verify_jobstats "$cmd" "ost1"
19423         # truncate
19424         cmd="$TRUNCATE $DIR/$tfile 0"
19425         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19426         # rename
19427         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19428         verify_jobstats "$cmd" "$SINGLEMDS"
19429         # jobstats expiry - sleep until old stats should be expired
19430         local left=$((new_interval + 5 - (SECONDS - start)))
19431         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19432                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19433                         "0" $left
19434         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19435         verify_jobstats "$cmd" "$SINGLEMDS"
19436         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19437             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19438
19439         # Ensure that jobid are present in changelog (if supported by MDS)
19440         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19441                 changelog_dump | tail -10
19442                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19443                 [ $jobids -eq 9 ] ||
19444                         error "Wrong changelog jobid count $jobids != 9"
19445
19446                 # LU-5862
19447                 JOBENV="disable"
19448                 jobstats_set $JOBENV
19449                 touch $DIR/$tfile
19450                 changelog_dump | grep $tfile
19451                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19452                 [ $jobids -eq 0 ] ||
19453                         error "Unexpected jobids when jobid_var=$JOBENV"
19454         fi
19455
19456         # test '%j' access to environment variable - if supported
19457         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19458                 JOBENV="JOBCOMPLEX"
19459                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19460
19461                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19462         fi
19463
19464         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19465                 JOBENV="JOBCOMPLEX"
19466                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19467
19468                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19469         fi
19470
19471         # test '%j' access to per-session jobid - if supported
19472         if lctl list_param jobid_this_session > /dev/null 2>&1
19473         then
19474                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19475                 lctl set_param jobid_this_session=$USER
19476
19477                 JOBENV="JOBCOMPLEX"
19478                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19479
19480                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19481         fi
19482 }
19483 run_test 205a "Verify job stats"
19484
19485 # LU-13117, LU-13597, LU-16599
19486 test_205b() {
19487         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19488                 skip "Need MDS version at least 2.13.54.91"
19489
19490         local job_stats="mdt.*.job_stats"
19491         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19492
19493         do_facet mds1 $LCTL set_param $job_stats=clear
19494
19495         # Setting jobid_var to USER might not be supported
19496         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19497         $LCTL set_param jobid_var=USER || true
19498         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19499         $LCTL set_param jobid_name="%j.%e.%u"
19500
19501         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19502         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19503                 { do_facet mds1 $LCTL get_param $job_stats;
19504                   error "Unexpected jobid found"; }
19505         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19506                 { do_facet mds1 $LCTL get_param $job_stats;
19507                   error "wrong job_stats format found"; }
19508
19509         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19510                 echo "MDS does not yet escape jobid" && return 0
19511
19512         mkdir_on_mdt0 $DIR/$tdir
19513         $LCTL set_param jobid_var=TEST205b
19514         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19515         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19516                       awk '/has\\x20sp/ {print $3}')
19517         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19518                   error "jobid not escaped"; }
19519
19520         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19521                 # need to run such a command on mds1:
19522                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19523                 #
19524                 # there might be multiple MDTs on single mds server, so need to
19525                 # specifiy MDT0000. Or the command will fail due to other MDTs
19526                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19527                         error "cannot clear escaped jobid in job_stats";
19528         else
19529                 echo "MDS does not support clearing escaped jobid"
19530         fi
19531 }
19532 run_test 205b "Verify job stats jobid and output format"
19533
19534 # LU-13733
19535 test_205c() {
19536         $LCTL set_param llite.*.stats=0
19537         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19538         $LCTL get_param llite.*.stats
19539         $LCTL get_param llite.*.stats | grep \
19540                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19541                         error "wrong client stats format found"
19542 }
19543 run_test 205c "Verify client stats format"
19544
19545 test_205d() {
19546         local file=$DIR/$tdir/$tfile
19547
19548         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19549                 skip "need lustre >= 2.15.53 for lljobstat"
19550         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19551                 skip "need lustre >= 2.15.53 for lljobstat"
19552         verify_yaml_available || skip_env "YAML verification not installed"
19553
19554         test_mkdir -i 0 $DIR/$tdir
19555         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19556
19557         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19558                 error "failed to write data to $file"
19559         mv $file $file.2
19560
19561         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19562         echo -n 'verify rename_stats...'
19563         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19564                 verify_yaml || error "rename_stats is not valid YAML"
19565         echo " OK"
19566
19567         echo -n 'verify mdt job_stats...'
19568         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19569                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19570         echo " OK"
19571
19572         echo -n 'verify ost job_stats...'
19573         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19574                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19575         echo " OK"
19576 }
19577 run_test 205d "verify the format of some stats files"
19578
19579 test_205e() {
19580         local ops_comma
19581         local file=$DIR/$tdir/$tfile
19582
19583         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19584                 skip "need lustre >= 2.15.53 for lljobstat"
19585         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19586                 skip "need lustre >= 2.15.53 for lljobstat"
19587         verify_yaml_available || skip_env "YAML verification not installed"
19588
19589         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19590
19591         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19592                 error "failed to create $file on ost1"
19593         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19594                 error "failed to write data to $file"
19595
19596         do_facet mds1 "$LCTL get_param *.*.job_stats"
19597         do_facet ost1 "$LCTL get_param *.*.job_stats"
19598
19599         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19600         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19601                 error "The output of lljobstat is not an valid YAML"
19602
19603         # verify that job dd.0 does exist and has some ops on ost1
19604         # typically this line is like:
19605         # - dd.0:            {ops: 20, ...}
19606         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19607                     awk '$2=="dd.0:" {print $4}')
19608
19609         (( ${ops_comma%,} >= 10 )) ||
19610                 error "cannot find job dd.0 with ops >= 10"
19611 }
19612 run_test 205e "verify the output of lljobstat"
19613
19614 test_205f() {
19615         verify_yaml_available || skip_env "YAML verification not installed"
19616
19617         # check both qos_ost_weights and qos_mdt_weights
19618         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19619         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19620                 error "qos_ost_weights is not valid YAML"
19621 }
19622 run_test 205f "verify qos_ost_weights YAML format "
19623
19624 # LU-1480, LU-1773 and LU-1657
19625 test_206() {
19626         mkdir -p $DIR/$tdir
19627         $LFS setstripe -c -1 $DIR/$tdir
19628 #define OBD_FAIL_LOV_INIT 0x1403
19629         $LCTL set_param fail_loc=0xa0001403
19630         $LCTL set_param fail_val=1
19631         touch $DIR/$tdir/$tfile || true
19632 }
19633 run_test 206 "fail lov_init_raid0() doesn't lbug"
19634
19635 test_207a() {
19636         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19637         local fsz=`stat -c %s $DIR/$tfile`
19638         cancel_lru_locks mdc
19639
19640         # do not return layout in getattr intent
19641 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19642         $LCTL set_param fail_loc=0x170
19643         local sz=`stat -c %s $DIR/$tfile`
19644
19645         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19646
19647         rm -rf $DIR/$tfile
19648 }
19649 run_test 207a "can refresh layout at glimpse"
19650
19651 test_207b() {
19652         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19653         local cksum=`md5sum $DIR/$tfile`
19654         local fsz=`stat -c %s $DIR/$tfile`
19655         cancel_lru_locks mdc
19656         cancel_lru_locks osc
19657
19658         # do not return layout in getattr intent
19659 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19660         $LCTL set_param fail_loc=0x171
19661
19662         # it will refresh layout after the file is opened but before read issues
19663         echo checksum is "$cksum"
19664         echo "$cksum" |md5sum -c --quiet || error "file differs"
19665
19666         rm -rf $DIR/$tfile
19667 }
19668 run_test 207b "can refresh layout at open"
19669
19670 test_208() {
19671         # FIXME: in this test suite, only RD lease is used. This is okay
19672         # for now as only exclusive open is supported. After generic lease
19673         # is done, this test suite should be revised. - Jinshan
19674
19675         remote_mds_nodsh && skip "remote MDS with nodsh"
19676         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19677                 skip "Need MDS version at least 2.4.52"
19678
19679         echo "==== test 1: verify get lease work"
19680         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19681
19682         echo "==== test 2: verify lease can be broken by upcoming open"
19683         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19684         local PID=$!
19685         sleep 2
19686
19687         $MULTIOP $DIR/$tfile oO_RDWR:c
19688         kill -USR1 $PID && wait $PID || error "break lease error"
19689
19690         echo "==== test 3: verify lease can't be granted if an open already exists"
19691         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19692         local PID=$!
19693         sleep 2
19694
19695         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19696         kill -USR1 $PID && wait $PID || error "open file error"
19697
19698         echo "==== test 4: lease can sustain over recovery"
19699         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19700         PID=$!
19701         sleep 2
19702
19703         fail mds1
19704
19705         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19706
19707         echo "==== test 5: lease broken can't be regained by replay"
19708         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19709         PID=$!
19710         sleep 2
19711
19712         # open file to break lease and then recovery
19713         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19714         fail mds1
19715
19716         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19717
19718         rm -f $DIR/$tfile
19719 }
19720 run_test 208 "Exclusive open"
19721
19722 test_209() {
19723         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19724                 skip_env "must have disp_stripe"
19725
19726         touch $DIR/$tfile
19727         sync; sleep 5; sync;
19728
19729         echo 3 > /proc/sys/vm/drop_caches
19730         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19731                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19732         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19733
19734         # open/close 500 times
19735         for i in $(seq 500); do
19736                 cat $DIR/$tfile
19737         done
19738
19739         echo 3 > /proc/sys/vm/drop_caches
19740         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19741                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19742         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19743
19744         echo "before: $req_before, after: $req_after"
19745         [ $((req_after - req_before)) -ge 300 ] &&
19746                 error "open/close requests are not freed"
19747         return 0
19748 }
19749 run_test 209 "read-only open/close requests should be freed promptly"
19750
19751 test_210() {
19752         local pid
19753
19754         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19755         pid=$!
19756         sleep 1
19757
19758         $LFS getstripe $DIR/$tfile
19759         kill -USR1 $pid
19760         wait $pid || error "multiop failed"
19761
19762         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19763         pid=$!
19764         sleep 1
19765
19766         $LFS getstripe $DIR/$tfile
19767         kill -USR1 $pid
19768         wait $pid || error "multiop failed"
19769 }
19770 run_test 210 "lfs getstripe does not break leases"
19771
19772 test_212() {
19773         size=`date +%s`
19774         size=$((size % 8192 + 1))
19775         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19776         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19777         rm -f $DIR/f212 $DIR/f212.xyz
19778 }
19779 run_test 212 "Sendfile test ============================================"
19780
19781 test_213() {
19782         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19783         cancel_lru_locks osc
19784         lctl set_param fail_loc=0x8000040f
19785         # generate a read lock
19786         cat $DIR/$tfile > /dev/null
19787         # write to the file, it will try to cancel the above read lock.
19788         cat /etc/hosts >> $DIR/$tfile
19789 }
19790 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19791
19792 test_214() { # for bug 20133
19793         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19794         for (( i=0; i < 340; i++ )) ; do
19795                 touch $DIR/$tdir/d214c/a$i
19796         done
19797
19798         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19799         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19800         ls $DIR/d214c || error "ls $DIR/d214c failed"
19801         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19802         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19803 }
19804 run_test 214 "hash-indexed directory test - bug 20133"
19805
19806 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19807 create_lnet_proc_files() {
19808         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19809 }
19810
19811 # counterpart of create_lnet_proc_files
19812 remove_lnet_proc_files() {
19813         rm -f $TMP/lnet_$1.sys
19814 }
19815
19816 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19817 # 3rd arg as regexp for body
19818 check_lnet_proc_stats() {
19819         local l=$(cat "$TMP/lnet_$1" |wc -l)
19820         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19821
19822         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19823 }
19824
19825 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19826 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19827 # optional and can be regexp for 2nd line (lnet.routes case)
19828 check_lnet_proc_entry() {
19829         local blp=2          # blp stands for 'position of 1st line of body'
19830         [ -z "$5" ] || blp=3 # lnet.routes case
19831
19832         local l=$(cat "$TMP/lnet_$1" |wc -l)
19833         # subtracting one from $blp because the body can be empty
19834         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19835
19836         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19837                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19838
19839         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19840                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19841
19842         # bail out if any unexpected line happened
19843         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19844         [ "$?" != 0 ] || error "$2 misformatted"
19845 }
19846
19847 test_215() { # for bugs 18102, 21079, 21517
19848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19849
19850         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19851         local P='[1-9][0-9]*'           # positive numeric
19852         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19853         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19854         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19855         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19856
19857         local L1 # regexp for 1st line
19858         local L2 # regexp for 2nd line (optional)
19859         local BR # regexp for the rest (body)
19860
19861         # lnet.stats should look as 11 space-separated non-negative numerics
19862         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19863         create_lnet_proc_files "stats"
19864         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19865         remove_lnet_proc_files "stats"
19866
19867         # lnet.routes should look like this:
19868         # Routing disabled/enabled
19869         # net hops priority state router
19870         # where net is a string like tcp0, hops > 0, priority >= 0,
19871         # state is up/down,
19872         # router is a string like 192.168.1.1@tcp2
19873         L1="^Routing (disabled|enabled)$"
19874         L2="^net +hops +priority +state +router$"
19875         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19876         create_lnet_proc_files "routes"
19877         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19878         remove_lnet_proc_files "routes"
19879
19880         # lnet.routers should look like this:
19881         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19882         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19883         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19884         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19885         L1="^ref +rtr_ref +alive +router$"
19886         BR="^$P +$P +(up|down) +$NID$"
19887         create_lnet_proc_files "routers"
19888         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19889         remove_lnet_proc_files "routers"
19890
19891         # lnet.peers should look like this:
19892         # nid refs state last max rtr min tx min queue
19893         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19894         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19895         # numeric (0 or >0 or <0), queue >= 0.
19896         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19897         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19898         create_lnet_proc_files "peers"
19899         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19900         remove_lnet_proc_files "peers"
19901
19902         # lnet.buffers  should look like this:
19903         # pages count credits min
19904         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19905         L1="^pages +count +credits +min$"
19906         BR="^ +$N +$N +$I +$I$"
19907         create_lnet_proc_files "buffers"
19908         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19909         remove_lnet_proc_files "buffers"
19910
19911         # lnet.nis should look like this:
19912         # nid status alive refs peer rtr max tx min
19913         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19914         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19915         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19916         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19917         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19918         create_lnet_proc_files "nis"
19919         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19920         remove_lnet_proc_files "nis"
19921
19922         # can we successfully write to lnet.stats?
19923         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19924 }
19925 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19926
19927 test_216() { # bug 20317
19928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19929         remote_ost_nodsh && skip "remote OST with nodsh"
19930
19931         local node
19932         local facets=$(get_facets OST)
19933         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19934
19935         save_lustre_params client "osc.*.contention_seconds" > $p
19936         save_lustre_params $facets \
19937                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19938         save_lustre_params $facets \
19939                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19940         save_lustre_params $facets \
19941                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19942         clear_stats osc.*.osc_stats
19943
19944         # agressive lockless i/o settings
19945         do_nodes $(comma_list $(osts_nodes)) \
19946                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19947                         ldlm.namespaces.filter-*.contended_locks=0 \
19948                         ldlm.namespaces.filter-*.contention_seconds=60"
19949         lctl set_param -n osc.*.contention_seconds=60
19950
19951         $DIRECTIO write $DIR/$tfile 0 10 4096
19952         $CHECKSTAT -s 40960 $DIR/$tfile
19953
19954         # disable lockless i/o
19955         do_nodes $(comma_list $(osts_nodes)) \
19956                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19957                         ldlm.namespaces.filter-*.contended_locks=32 \
19958                         ldlm.namespaces.filter-*.contention_seconds=0"
19959         lctl set_param -n osc.*.contention_seconds=0
19960         clear_stats osc.*.osc_stats
19961
19962         dd if=/dev/zero of=$DIR/$tfile count=0
19963         $CHECKSTAT -s 0 $DIR/$tfile
19964
19965         restore_lustre_params <$p
19966         rm -f $p
19967         rm $DIR/$tfile
19968 }
19969 run_test 216 "check lockless direct write updates file size and kms correctly"
19970
19971 test_217() { # bug 22430
19972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19973
19974         local node
19975         local nid
19976
19977         for node in $(nodes_list); do
19978                 nid=$(host_nids_address $node $NETTYPE)
19979                 if [[ $nid = *-* ]] ; then
19980                         echo "lctl ping $(h2nettype $nid)"
19981                         lctl ping $(h2nettype $nid)
19982                 else
19983                         echo "skipping $node (no hyphen detected)"
19984                 fi
19985         done
19986 }
19987 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19988
19989 test_218() {
19990        # do directio so as not to populate the page cache
19991        log "creating a 10 Mb file"
19992        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19993        log "starting reads"
19994        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19995        log "truncating the file"
19996        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19997        log "killing dd"
19998        kill %+ || true # reads might have finished
19999        echo "wait until dd is finished"
20000        wait
20001        log "removing the temporary file"
20002        rm -rf $DIR/$tfile || error "tmp file removal failed"
20003 }
20004 run_test 218 "parallel read and truncate should not deadlock"
20005
20006 test_219() {
20007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20008
20009         # write one partial page
20010         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20011         # set no grant so vvp_io_commit_write will do sync write
20012         $LCTL set_param fail_loc=0x411
20013         # write a full page at the end of file
20014         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20015
20016         $LCTL set_param fail_loc=0
20017         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20018         $LCTL set_param fail_loc=0x411
20019         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20020
20021         # LU-4201
20022         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20023         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20024 }
20025 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20026
20027 test_220() { #LU-325
20028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20029         remote_ost_nodsh && skip "remote OST with nodsh"
20030         remote_mds_nodsh && skip "remote MDS with nodsh"
20031         remote_mgs_nodsh && skip "remote MGS with nodsh"
20032
20033         local OSTIDX=0
20034
20035         # create on MDT0000 so the last_id and next_id are correct
20036         mkdir_on_mdt0 $DIR/$tdir
20037         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20038         OST=${OST%_UUID}
20039
20040         # on the mdt's osc
20041         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20042         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20043                         osp.$mdtosc_proc1.prealloc_last_id)
20044         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20045                         osp.$mdtosc_proc1.prealloc_next_id)
20046
20047         $LFS df -i
20048
20049         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20050         #define OBD_FAIL_OST_ENOINO              0x229
20051         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20052         create_pool $FSNAME.$TESTNAME || return 1
20053         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20054
20055         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20056
20057         MDSOBJS=$((last_id - next_id))
20058         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20059
20060         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20061         echo "OST still has $count kbytes free"
20062
20063         echo "create $MDSOBJS files @next_id..."
20064         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20065
20066         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20067                         osp.$mdtosc_proc1.prealloc_last_id)
20068         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20069                         osp.$mdtosc_proc1.prealloc_next_id)
20070
20071         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20072         $LFS df -i
20073
20074         echo "cleanup..."
20075
20076         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20077         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20078
20079         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20080                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20081         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20082                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20083         echo "unlink $MDSOBJS files @$next_id..."
20084         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20085 }
20086 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20087
20088 test_221() {
20089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20090
20091         dd if=`which date` of=$MOUNT/date oflag=sync
20092         chmod +x $MOUNT/date
20093
20094         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20095         $LCTL set_param fail_loc=0x80001401
20096
20097         $MOUNT/date > /dev/null
20098         rm -f $MOUNT/date
20099 }
20100 run_test 221 "make sure fault and truncate race to not cause OOM"
20101
20102 test_222a () {
20103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20104
20105         rm -rf $DIR/$tdir
20106         test_mkdir $DIR/$tdir
20107         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20108         createmany -o $DIR/$tdir/$tfile 10
20109         cancel_lru_locks mdc
20110         cancel_lru_locks osc
20111         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20112         $LCTL set_param fail_loc=0x31a
20113         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20114         $LCTL set_param fail_loc=0
20115         rm -r $DIR/$tdir
20116 }
20117 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20118
20119 test_222b () {
20120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20121
20122         rm -rf $DIR/$tdir
20123         test_mkdir $DIR/$tdir
20124         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20125         createmany -o $DIR/$tdir/$tfile 10
20126         cancel_lru_locks mdc
20127         cancel_lru_locks osc
20128         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20129         $LCTL set_param fail_loc=0x31a
20130         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20131         $LCTL set_param fail_loc=0
20132 }
20133 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20134
20135 test_223 () {
20136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20137
20138         rm -rf $DIR/$tdir
20139         test_mkdir $DIR/$tdir
20140         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20141         createmany -o $DIR/$tdir/$tfile 10
20142         cancel_lru_locks mdc
20143         cancel_lru_locks osc
20144         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20145         $LCTL set_param fail_loc=0x31b
20146         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20147         $LCTL set_param fail_loc=0
20148         rm -r $DIR/$tdir
20149 }
20150 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20151
20152 test_224a() { # LU-1039, MRP-303
20153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20154         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20155         $LCTL set_param fail_loc=0x508
20156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20157         $LCTL set_param fail_loc=0
20158         df $DIR
20159 }
20160 run_test 224a "Don't panic on bulk IO failure"
20161
20162 test_224bd_sub() { # LU-1039, MRP-303
20163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20164         local timeout=$1
20165
20166         shift
20167         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20168
20169         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20170
20171         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20172         cancel_lru_locks osc
20173         set_checksums 0
20174         stack_trap "set_checksums $ORIG_CSUM" EXIT
20175         local at_max_saved=0
20176
20177         # adaptive timeouts may prevent seeing the issue
20178         if at_is_enabled; then
20179                 at_max_saved=$(at_max_get mds)
20180                 at_max_set 0 mds client
20181                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20182         fi
20183
20184         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20185         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20186         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20187
20188         do_facet ost1 $LCTL set_param fail_loc=0
20189         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20190         df $DIR
20191 }
20192
20193 test_224b() {
20194         test_224bd_sub 3 error "dd failed"
20195 }
20196 run_test 224b "Don't panic on bulk IO failure"
20197
20198 test_224c() { # LU-6441
20199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20200         remote_mds_nodsh && skip "remote MDS with nodsh"
20201
20202         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20203         save_writethrough $p
20204         set_cache writethrough on
20205
20206         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20207         local at_max=$($LCTL get_param -n at_max)
20208         local timeout=$($LCTL get_param -n timeout)
20209         local test_at="at_max"
20210         local param_at="$FSNAME.sys.at_max"
20211         local test_timeout="timeout"
20212         local param_timeout="$FSNAME.sys.timeout"
20213
20214         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20215
20216         set_persistent_param_and_check client "$test_at" "$param_at" 0
20217         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20218
20219         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20220         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20221         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20222         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20223         sync
20224         do_facet ost1 "$LCTL set_param fail_loc=0"
20225
20226         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20227         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20228                 $timeout
20229
20230         $LCTL set_param -n $pages_per_rpc
20231         restore_lustre_params < $p
20232         rm -f $p
20233 }
20234 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20235
20236 test_224d() { # LU-11169
20237         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20238 }
20239 run_test 224d "Don't corrupt data on bulk IO timeout"
20240
20241 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20242 test_225a () {
20243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20244         if [ -z ${MDSSURVEY} ]; then
20245                 skip_env "mds-survey not found"
20246         fi
20247         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20248                 skip "Need MDS version at least 2.2.51"
20249
20250         local mds=$(facet_host $SINGLEMDS)
20251         local target=$(do_nodes $mds 'lctl dl' |
20252                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20253
20254         local cmd1="file_count=1000 thrhi=4"
20255         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20256         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20257         local cmd="$cmd1 $cmd2 $cmd3"
20258
20259         rm -f ${TMP}/mds_survey*
20260         echo + $cmd
20261         eval $cmd || error "mds-survey with zero-stripe failed"
20262         cat ${TMP}/mds_survey*
20263         rm -f ${TMP}/mds_survey*
20264 }
20265 run_test 225a "Metadata survey sanity with zero-stripe"
20266
20267 test_225b () {
20268         if [ -z ${MDSSURVEY} ]; then
20269                 skip_env "mds-survey not found"
20270         fi
20271         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20272                 skip "Need MDS version at least 2.2.51"
20273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20274         remote_mds_nodsh && skip "remote MDS with nodsh"
20275         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20276                 skip_env "Need to mount OST to test"
20277         fi
20278
20279         local mds=$(facet_host $SINGLEMDS)
20280         local target=$(do_nodes $mds 'lctl dl' |
20281                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20282
20283         local cmd1="file_count=1000 thrhi=4"
20284         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20285         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20286         local cmd="$cmd1 $cmd2 $cmd3"
20287
20288         rm -f ${TMP}/mds_survey*
20289         echo + $cmd
20290         eval $cmd || error "mds-survey with stripe_count failed"
20291         cat ${TMP}/mds_survey*
20292         rm -f ${TMP}/mds_survey*
20293 }
20294 run_test 225b "Metadata survey sanity with stripe_count = 1"
20295
20296 mcreate_path2fid () {
20297         local mode=$1
20298         local major=$2
20299         local minor=$3
20300         local name=$4
20301         local desc=$5
20302         local path=$DIR/$tdir/$name
20303         local fid
20304         local rc
20305         local fid_path
20306
20307         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20308                 error "cannot create $desc"
20309
20310         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20311         rc=$?
20312         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20313
20314         fid_path=$($LFS fid2path $MOUNT $fid)
20315         rc=$?
20316         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20317
20318         [ "$path" == "$fid_path" ] ||
20319                 error "fid2path returned $fid_path, expected $path"
20320
20321         echo "pass with $path and $fid"
20322 }
20323
20324 test_226a () {
20325         rm -rf $DIR/$tdir
20326         mkdir -p $DIR/$tdir
20327
20328         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20329         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20330         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20331         mcreate_path2fid 0040666 0 0 dir "directory"
20332         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20333         mcreate_path2fid 0100666 0 0 file "regular file"
20334         mcreate_path2fid 0120666 0 0 link "symbolic link"
20335         mcreate_path2fid 0140666 0 0 sock "socket"
20336 }
20337 run_test 226a "call path2fid and fid2path on files of all type"
20338
20339 test_226b () {
20340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20341
20342         local MDTIDX=1
20343
20344         rm -rf $DIR/$tdir
20345         mkdir -p $DIR/$tdir
20346         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20347                 error "create remote directory failed"
20348         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20349         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20350                                 "character special file (null)"
20351         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20352                                 "character special file (no device)"
20353         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20354         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20355                                 "block special file (loop)"
20356         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20357         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20358         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20359 }
20360 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20361
20362 test_226c () {
20363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20364         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20365                 skip "Need MDS version at least 2.13.55"
20366
20367         local submnt=/mnt/submnt
20368         local srcfile=/etc/passwd
20369         local dstfile=$submnt/passwd
20370         local path
20371         local fid
20372
20373         rm -rf $DIR/$tdir
20374         rm -rf $submnt
20375         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20376                 error "create remote directory failed"
20377         mkdir -p $submnt || error "create $submnt failed"
20378         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20379                 error "mount $submnt failed"
20380         stack_trap "umount $submnt" EXIT
20381
20382         cp $srcfile $dstfile
20383         fid=$($LFS path2fid $dstfile)
20384         path=$($LFS fid2path $submnt "$fid")
20385         [ "$path" = "$dstfile" ] ||
20386                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20387 }
20388 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20389
20390 # LU-1299 Executing or running ldd on a truncated executable does not
20391 # cause an out-of-memory condition.
20392 test_227() {
20393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20394         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20395
20396         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20397         chmod +x $MOUNT/date
20398
20399         $MOUNT/date > /dev/null
20400         ldd $MOUNT/date > /dev/null
20401         rm -f $MOUNT/date
20402 }
20403 run_test 227 "running truncated executable does not cause OOM"
20404
20405 # LU-1512 try to reuse idle OI blocks
20406 test_228a() {
20407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20408         remote_mds_nodsh && skip "remote MDS with nodsh"
20409         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20410
20411         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20412         local myDIR=$DIR/$tdir
20413
20414         mkdir -p $myDIR
20415         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20416         $LCTL set_param fail_loc=0x80001002
20417         createmany -o $myDIR/t- 10000
20418         $LCTL set_param fail_loc=0
20419         # The guard is current the largest FID holder
20420         touch $myDIR/guard
20421         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20422                     tr -d '[')
20423         local IDX=$(($SEQ % 64))
20424
20425         do_facet $SINGLEMDS sync
20426         # Make sure journal flushed.
20427         sleep 6
20428         local blk1=$(do_facet $SINGLEMDS \
20429                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20430                      grep Blockcount | awk '{print $4}')
20431
20432         # Remove old files, some OI blocks will become idle.
20433         unlinkmany $myDIR/t- 10000
20434         # Create new files, idle OI blocks should be reused.
20435         createmany -o $myDIR/t- 2000
20436         do_facet $SINGLEMDS sync
20437         # Make sure journal flushed.
20438         sleep 6
20439         local blk2=$(do_facet $SINGLEMDS \
20440                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20441                      grep Blockcount | awk '{print $4}')
20442
20443         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20444 }
20445 run_test 228a "try to reuse idle OI blocks"
20446
20447 test_228b() {
20448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20449         remote_mds_nodsh && skip "remote MDS with nodsh"
20450         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20451
20452         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20453         local myDIR=$DIR/$tdir
20454
20455         mkdir -p $myDIR
20456         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20457         $LCTL set_param fail_loc=0x80001002
20458         createmany -o $myDIR/t- 10000
20459         $LCTL set_param fail_loc=0
20460         # The guard is current the largest FID holder
20461         touch $myDIR/guard
20462         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20463                     tr -d '[')
20464         local IDX=$(($SEQ % 64))
20465
20466         do_facet $SINGLEMDS sync
20467         # Make sure journal flushed.
20468         sleep 6
20469         local blk1=$(do_facet $SINGLEMDS \
20470                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20471                      grep Blockcount | awk '{print $4}')
20472
20473         # Remove old files, some OI blocks will become idle.
20474         unlinkmany $myDIR/t- 10000
20475
20476         # stop the MDT
20477         stop $SINGLEMDS || error "Fail to stop MDT."
20478         # remount the MDT
20479         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20480                 error "Fail to start MDT."
20481
20482         client_up || error "Fail to df."
20483         # Create new files, idle OI blocks should be reused.
20484         createmany -o $myDIR/t- 2000
20485         do_facet $SINGLEMDS sync
20486         # Make sure journal flushed.
20487         sleep 6
20488         local blk2=$(do_facet $SINGLEMDS \
20489                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20490                      grep Blockcount | awk '{print $4}')
20491
20492         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20493 }
20494 run_test 228b "idle OI blocks can be reused after MDT restart"
20495
20496 #LU-1881
20497 test_228c() {
20498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20499         remote_mds_nodsh && skip "remote MDS with nodsh"
20500         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20501
20502         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20503         local myDIR=$DIR/$tdir
20504
20505         mkdir -p $myDIR
20506         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20507         $LCTL set_param fail_loc=0x80001002
20508         # 20000 files can guarantee there are index nodes in the OI file
20509         createmany -o $myDIR/t- 20000
20510         $LCTL set_param fail_loc=0
20511         # The guard is current the largest FID holder
20512         touch $myDIR/guard
20513         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20514                     tr -d '[')
20515         local IDX=$(($SEQ % 64))
20516
20517         do_facet $SINGLEMDS sync
20518         # Make sure journal flushed.
20519         sleep 6
20520         local blk1=$(do_facet $SINGLEMDS \
20521                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20522                      grep Blockcount | awk '{print $4}')
20523
20524         # Remove old files, some OI blocks will become idle.
20525         unlinkmany $myDIR/t- 20000
20526         rm -f $myDIR/guard
20527         # The OI file should become empty now
20528
20529         # Create new files, idle OI blocks should be reused.
20530         createmany -o $myDIR/t- 2000
20531         do_facet $SINGLEMDS sync
20532         # Make sure journal flushed.
20533         sleep 6
20534         local blk2=$(do_facet $SINGLEMDS \
20535                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20536                      grep Blockcount | awk '{print $4}')
20537
20538         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20539 }
20540 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20541
20542 test_229() { # LU-2482, LU-3448
20543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20544         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20545         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20546                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20547
20548         rm -f $DIR/$tfile
20549
20550         # Create a file with a released layout and stripe count 2.
20551         $MULTIOP $DIR/$tfile H2c ||
20552                 error "failed to create file with released layout"
20553
20554         $LFS getstripe -v $DIR/$tfile
20555
20556         local pattern=$($LFS getstripe -L $DIR/$tfile)
20557         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20558
20559         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20560                 error "getstripe"
20561         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20562         stat $DIR/$tfile || error "failed to stat released file"
20563
20564         chown $RUNAS_ID $DIR/$tfile ||
20565                 error "chown $RUNAS_ID $DIR/$tfile failed"
20566
20567         chgrp $RUNAS_ID $DIR/$tfile ||
20568                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20569
20570         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20571         rm $DIR/$tfile || error "failed to remove released file"
20572 }
20573 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20574
20575 test_230a() {
20576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20578         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20579                 skip "Need MDS version at least 2.11.52"
20580
20581         local MDTIDX=1
20582
20583         test_mkdir $DIR/$tdir
20584         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20585         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20586         [ $mdt_idx -ne 0 ] &&
20587                 error "create local directory on wrong MDT $mdt_idx"
20588
20589         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20590                         error "create remote directory failed"
20591         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20592         [ $mdt_idx -ne $MDTIDX ] &&
20593                 error "create remote directory on wrong MDT $mdt_idx"
20594
20595         createmany -o $DIR/$tdir/test_230/t- 10 ||
20596                 error "create files on remote directory failed"
20597         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20598         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20599         rm -r $DIR/$tdir || error "unlink remote directory failed"
20600 }
20601 run_test 230a "Create remote directory and files under the remote directory"
20602
20603 test_230b() {
20604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20606         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20607                 skip "Need MDS version at least 2.11.52"
20608
20609         local MDTIDX=1
20610         local mdt_index
20611         local i
20612         local file
20613         local pid
20614         local stripe_count
20615         local migrate_dir=$DIR/$tdir/migrate_dir
20616         local other_dir=$DIR/$tdir/other_dir
20617
20618         test_mkdir $DIR/$tdir
20619         test_mkdir -i0 -c1 $migrate_dir
20620         test_mkdir -i0 -c1 $other_dir
20621         for ((i=0; i<10; i++)); do
20622                 mkdir -p $migrate_dir/dir_${i}
20623                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20624                         error "create files under remote dir failed $i"
20625         done
20626
20627         cp /etc/passwd $migrate_dir/$tfile
20628         cp /etc/passwd $other_dir/$tfile
20629         chattr +SAD $migrate_dir
20630         chattr +SAD $migrate_dir/$tfile
20631
20632         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20633         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20634         local old_dir_mode=$(stat -c%f $migrate_dir)
20635         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20636
20637         mkdir -p $migrate_dir/dir_default_stripe2
20638         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20639         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20640
20641         mkdir -p $other_dir
20642         ln $migrate_dir/$tfile $other_dir/luna
20643         ln $migrate_dir/$tfile $migrate_dir/sofia
20644         ln $other_dir/$tfile $migrate_dir/david
20645         ln -s $migrate_dir/$tfile $other_dir/zachary
20646         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20647         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20648
20649         local len
20650         local lnktgt
20651
20652         # inline symlink
20653         for len in 58 59 60; do
20654                 lnktgt=$(str_repeat 'l' $len)
20655                 touch $migrate_dir/$lnktgt
20656                 ln -s $lnktgt $migrate_dir/${len}char_ln
20657         done
20658
20659         # PATH_MAX
20660         for len in 4094 4095; do
20661                 lnktgt=$(str_repeat 'l' $len)
20662                 ln -s $lnktgt $migrate_dir/${len}char_ln
20663         done
20664
20665         # NAME_MAX
20666         for len in 254 255; do
20667                 touch $migrate_dir/$(str_repeat 'l' $len)
20668         done
20669
20670         $LFS migrate -m $MDTIDX $migrate_dir ||
20671                 error "fails on migrating remote dir to MDT1"
20672
20673         echo "migratate to MDT1, then checking.."
20674         for ((i = 0; i < 10; i++)); do
20675                 for file in $(find $migrate_dir/dir_${i}); do
20676                         mdt_index=$($LFS getstripe -m $file)
20677                         # broken symlink getstripe will fail
20678                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20679                                 error "$file is not on MDT${MDTIDX}"
20680                 done
20681         done
20682
20683         # the multiple link file should still in MDT0
20684         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20685         [ $mdt_index == 0 ] ||
20686                 error "$file is not on MDT${MDTIDX}"
20687
20688         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20689         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20690                 error " expect $old_dir_flag get $new_dir_flag"
20691
20692         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20693         [ "$old_file_flag" = "$new_file_flag" ] ||
20694                 error " expect $old_file_flag get $new_file_flag"
20695
20696         local new_dir_mode=$(stat -c%f $migrate_dir)
20697         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20698                 error "expect mode $old_dir_mode get $new_dir_mode"
20699
20700         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20701         [ "$old_file_mode" = "$new_file_mode" ] ||
20702                 error "expect mode $old_file_mode get $new_file_mode"
20703
20704         diff /etc/passwd $migrate_dir/$tfile ||
20705                 error "$tfile different after migration"
20706
20707         diff /etc/passwd $other_dir/luna ||
20708                 error "luna different after migration"
20709
20710         diff /etc/passwd $migrate_dir/sofia ||
20711                 error "sofia different after migration"
20712
20713         diff /etc/passwd $migrate_dir/david ||
20714                 error "david different after migration"
20715
20716         diff /etc/passwd $other_dir/zachary ||
20717                 error "zachary different after migration"
20718
20719         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20720                 error "${tfile}_ln different after migration"
20721
20722         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20723                 error "${tfile}_ln_other different after migration"
20724
20725         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20726         [ $stripe_count = 2 ] ||
20727                 error "dir strpe_count $d != 2 after migration."
20728
20729         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20730         [ $stripe_count = 2 ] ||
20731                 error "file strpe_count $d != 2 after migration."
20732
20733         #migrate back to MDT0
20734         MDTIDX=0
20735
20736         $LFS migrate -m $MDTIDX $migrate_dir ||
20737                 error "fails on migrating remote dir to MDT0"
20738
20739         echo "migrate back to MDT0, checking.."
20740         for file in $(find $migrate_dir); do
20741                 mdt_index=$($LFS getstripe -m $file)
20742                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20743                         error "$file is not on MDT${MDTIDX}"
20744         done
20745
20746         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20747         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20748                 error " expect $old_dir_flag get $new_dir_flag"
20749
20750         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20751         [ "$old_file_flag" = "$new_file_flag" ] ||
20752                 error " expect $old_file_flag get $new_file_flag"
20753
20754         local new_dir_mode=$(stat -c%f $migrate_dir)
20755         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20756                 error "expect mode $old_dir_mode get $new_dir_mode"
20757
20758         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20759         [ "$old_file_mode" = "$new_file_mode" ] ||
20760                 error "expect mode $old_file_mode get $new_file_mode"
20761
20762         diff /etc/passwd ${migrate_dir}/$tfile ||
20763                 error "$tfile different after migration"
20764
20765         diff /etc/passwd ${other_dir}/luna ||
20766                 error "luna different after migration"
20767
20768         diff /etc/passwd ${migrate_dir}/sofia ||
20769                 error "sofia different after migration"
20770
20771         diff /etc/passwd ${other_dir}/zachary ||
20772                 error "zachary different after migration"
20773
20774         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20775                 error "${tfile}_ln different after migration"
20776
20777         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20778                 error "${tfile}_ln_other different after migration"
20779
20780         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20781         [ $stripe_count = 2 ] ||
20782                 error "dir strpe_count $d != 2 after migration."
20783
20784         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20785         [ $stripe_count = 2 ] ||
20786                 error "file strpe_count $d != 2 after migration."
20787
20788         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20789 }
20790 run_test 230b "migrate directory"
20791
20792 test_230c() {
20793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20795         remote_mds_nodsh && skip "remote MDS with nodsh"
20796         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20797                 skip "Need MDS version at least 2.11.52"
20798
20799         local MDTIDX=1
20800         local total=3
20801         local mdt_index
20802         local file
20803         local migrate_dir=$DIR/$tdir/migrate_dir
20804
20805         #If migrating directory fails in the middle, all entries of
20806         #the directory is still accessiable.
20807         test_mkdir $DIR/$tdir
20808         test_mkdir -i0 -c1 $migrate_dir
20809         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20810         stat $migrate_dir
20811         createmany -o $migrate_dir/f $total ||
20812                 error "create files under ${migrate_dir} failed"
20813
20814         # fail after migrating top dir, and this will fail only once, so the
20815         # first sub file migration will fail (currently f3), others succeed.
20816         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20817         do_facet mds1 lctl set_param fail_loc=0x1801
20818         local t=$(ls $migrate_dir | wc -l)
20819         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20820                 error "migrate should fail"
20821         local u=$(ls $migrate_dir | wc -l)
20822         [ "$u" == "$t" ] || error "$u != $t during migration"
20823
20824         # add new dir/file should succeed
20825         mkdir $migrate_dir/dir ||
20826                 error "mkdir failed under migrating directory"
20827         touch $migrate_dir/file ||
20828                 error "create file failed under migrating directory"
20829
20830         # add file with existing name should fail
20831         for file in $migrate_dir/f*; do
20832                 stat $file > /dev/null || error "stat $file failed"
20833                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20834                         error "open(O_CREAT|O_EXCL) $file should fail"
20835                 $MULTIOP $file m && error "create $file should fail"
20836                 touch $DIR/$tdir/remote_dir/$tfile ||
20837                         error "touch $tfile failed"
20838                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20839                         error "link $file should fail"
20840                 mdt_index=$($LFS getstripe -m $file)
20841                 if [ $mdt_index == 0 ]; then
20842                         # file failed to migrate is not allowed to rename to
20843                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20844                                 error "rename to $file should fail"
20845                 else
20846                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20847                                 error "rename to $file failed"
20848                 fi
20849                 echo hello >> $file || error "write $file failed"
20850         done
20851
20852         # resume migration with different options should fail
20853         $LFS migrate -m 0 $migrate_dir &&
20854                 error "migrate -m 0 $migrate_dir should fail"
20855
20856         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20857                 error "migrate -c 2 $migrate_dir should fail"
20858
20859         # resume migration should succeed
20860         $LFS migrate -m $MDTIDX $migrate_dir ||
20861                 error "migrate $migrate_dir failed"
20862
20863         echo "Finish migration, then checking.."
20864         for file in $(find $migrate_dir); do
20865                 mdt_index=$($LFS getstripe -m $file)
20866                 [ $mdt_index == $MDTIDX ] ||
20867                         error "$file is not on MDT${MDTIDX}"
20868         done
20869
20870         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20871 }
20872 run_test 230c "check directory accessiblity if migration failed"
20873
20874 test_230d() {
20875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20876         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20877         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20878                 skip "Need MDS version at least 2.11.52"
20879         # LU-11235
20880         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20881
20882         local migrate_dir=$DIR/$tdir/migrate_dir
20883         local old_index
20884         local new_index
20885         local old_count
20886         local new_count
20887         local new_hash
20888         local mdt_index
20889         local i
20890         local j
20891
20892         old_index=$((RANDOM % MDSCOUNT))
20893         old_count=$((MDSCOUNT - old_index))
20894         new_index=$((RANDOM % MDSCOUNT))
20895         new_count=$((MDSCOUNT - new_index))
20896         new_hash=1 # for all_char
20897
20898         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20899         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20900
20901         test_mkdir $DIR/$tdir
20902         test_mkdir -i $old_index -c $old_count $migrate_dir
20903
20904         for ((i=0; i<100; i++)); do
20905                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20906                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20907                         error "create files under remote dir failed $i"
20908         done
20909
20910         echo -n "Migrate from MDT$old_index "
20911         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20912         echo -n "to MDT$new_index"
20913         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20914         echo
20915
20916         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20917         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20918                 error "migrate remote dir error"
20919
20920         echo "Finish migration, then checking.."
20921         for file in $(find $migrate_dir -maxdepth 1); do
20922                 mdt_index=$($LFS getstripe -m $file)
20923                 if [ $mdt_index -lt $new_index ] ||
20924                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20925                         error "$file is on MDT$mdt_index"
20926                 fi
20927         done
20928
20929         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20930 }
20931 run_test 230d "check migrate big directory"
20932
20933 test_230e() {
20934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20936         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20937                 skip "Need MDS version at least 2.11.52"
20938
20939         local i
20940         local j
20941         local a_fid
20942         local b_fid
20943
20944         mkdir_on_mdt0 $DIR/$tdir
20945         mkdir $DIR/$tdir/migrate_dir
20946         mkdir $DIR/$tdir/other_dir
20947         touch $DIR/$tdir/migrate_dir/a
20948         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20949         ls $DIR/$tdir/other_dir
20950
20951         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20952                 error "migrate dir fails"
20953
20954         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20955         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20956
20957         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20958         [ $mdt_index == 0 ] || error "a is not on MDT0"
20959
20960         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20961                 error "migrate dir fails"
20962
20963         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20964         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20965
20966         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20967         [ $mdt_index == 1 ] || error "a is not on MDT1"
20968
20969         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20970         [ $mdt_index == 1 ] || error "b is not on MDT1"
20971
20972         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20973         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20974
20975         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20976
20977         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20978 }
20979 run_test 230e "migrate mulitple local link files"
20980
20981 test_230f() {
20982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20984         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20985                 skip "Need MDS version at least 2.11.52"
20986
20987         local a_fid
20988         local ln_fid
20989
20990         mkdir -p $DIR/$tdir
20991         mkdir $DIR/$tdir/migrate_dir
20992         $LFS mkdir -i1 $DIR/$tdir/other_dir
20993         touch $DIR/$tdir/migrate_dir/a
20994         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20995         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20996         ls $DIR/$tdir/other_dir
20997
20998         # a should be migrated to MDT1, since no other links on MDT0
20999         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21000                 error "#1 migrate dir fails"
21001         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21002         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21003         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21004         [ $mdt_index == 1 ] || error "a is not on MDT1"
21005
21006         # a should stay on MDT1, because it is a mulitple link file
21007         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21008                 error "#2 migrate dir fails"
21009         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21010         [ $mdt_index == 1 ] || error "a is not on MDT1"
21011
21012         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21013                 error "#3 migrate dir fails"
21014
21015         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21016         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21017         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21018
21019         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21020         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21021
21022         # a should be migrated to MDT0, since no other links on MDT1
21023         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21024                 error "#4 migrate dir fails"
21025         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21026         [ $mdt_index == 0 ] || error "a is not on MDT0"
21027
21028         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21029 }
21030 run_test 230f "migrate mulitple remote link files"
21031
21032 test_230g() {
21033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21034         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21035         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21036                 skip "Need MDS version at least 2.11.52"
21037
21038         mkdir -p $DIR/$tdir/migrate_dir
21039
21040         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21041                 error "migrating dir to non-exist MDT succeeds"
21042         true
21043 }
21044 run_test 230g "migrate dir to non-exist MDT"
21045
21046 test_230h() {
21047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21049         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21050                 skip "Need MDS version at least 2.11.52"
21051
21052         local mdt_index
21053
21054         mkdir -p $DIR/$tdir/migrate_dir
21055
21056         $LFS migrate -m1 $DIR &&
21057                 error "migrating mountpoint1 should fail"
21058
21059         $LFS migrate -m1 $DIR/$tdir/.. &&
21060                 error "migrating mountpoint2 should fail"
21061
21062         # same as mv
21063         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21064                 error "migrating $tdir/migrate_dir/.. should fail"
21065
21066         true
21067 }
21068 run_test 230h "migrate .. and root"
21069
21070 test_230i() {
21071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21072         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21073         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21074                 skip "Need MDS version at least 2.11.52"
21075
21076         mkdir -p $DIR/$tdir/migrate_dir
21077
21078         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21079                 error "migration fails with a tailing slash"
21080
21081         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21082                 error "migration fails with two tailing slashes"
21083 }
21084 run_test 230i "lfs migrate -m tolerates trailing slashes"
21085
21086 test_230j() {
21087         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21088         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21089                 skip "Need MDS version at least 2.11.52"
21090
21091         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21092         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21093                 error "create $tfile failed"
21094         cat /etc/passwd > $DIR/$tdir/$tfile
21095
21096         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21097
21098         cmp /etc/passwd $DIR/$tdir/$tfile ||
21099                 error "DoM file mismatch after migration"
21100 }
21101 run_test 230j "DoM file data not changed after dir migration"
21102
21103 test_230k() {
21104         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21105         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21106                 skip "Need MDS version at least 2.11.56"
21107
21108         local total=20
21109         local files_on_starting_mdt=0
21110
21111         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21112         $LFS getdirstripe $DIR/$tdir
21113         for i in $(seq $total); do
21114                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21115                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21116                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21117         done
21118
21119         echo "$files_on_starting_mdt files on MDT0"
21120
21121         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21122         $LFS getdirstripe $DIR/$tdir
21123
21124         files_on_starting_mdt=0
21125         for i in $(seq $total); do
21126                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21127                         error "file $tfile.$i mismatch after migration"
21128                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21129                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21130         done
21131
21132         echo "$files_on_starting_mdt files on MDT1 after migration"
21133         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21134
21135         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21136         $LFS getdirstripe $DIR/$tdir
21137
21138         files_on_starting_mdt=0
21139         for i in $(seq $total); do
21140                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21141                         error "file $tfile.$i mismatch after 2nd migration"
21142                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21143                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21144         done
21145
21146         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21147         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21148
21149         true
21150 }
21151 run_test 230k "file data not changed after dir migration"
21152
21153 test_230l() {
21154         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21155         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21156                 skip "Need MDS version at least 2.11.56"
21157
21158         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21159         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21160                 error "create files under remote dir failed $i"
21161         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21162 }
21163 run_test 230l "readdir between MDTs won't crash"
21164
21165 test_230m() {
21166         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21167         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21168                 skip "Need MDS version at least 2.11.56"
21169
21170         local MDTIDX=1
21171         local mig_dir=$DIR/$tdir/migrate_dir
21172         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21173         local shortstr="b"
21174         local val
21175
21176         echo "Creating files and dirs with xattrs"
21177         test_mkdir $DIR/$tdir
21178         test_mkdir -i0 -c1 $mig_dir
21179         mkdir $mig_dir/dir
21180         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21181                 error "cannot set xattr attr1 on dir"
21182         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21183                 error "cannot set xattr attr2 on dir"
21184         touch $mig_dir/dir/f0
21185         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21186                 error "cannot set xattr attr1 on file"
21187         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21188                 error "cannot set xattr attr2 on file"
21189         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21190         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21191         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21192         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21193         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21194         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21195         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21196         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21197         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21198
21199         echo "Migrating to MDT1"
21200         $LFS migrate -m $MDTIDX $mig_dir ||
21201                 error "fails on migrating dir to MDT1"
21202
21203         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21204         echo "Checking xattrs"
21205         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21206         [ "$val" = $longstr ] ||
21207                 error "expecting xattr1 $longstr on dir, found $val"
21208         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21209         [ "$val" = $shortstr ] ||
21210                 error "expecting xattr2 $shortstr on dir, found $val"
21211         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21212         [ "$val" = $longstr ] ||
21213                 error "expecting xattr1 $longstr on file, found $val"
21214         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21215         [ "$val" = $shortstr ] ||
21216                 error "expecting xattr2 $shortstr on file, found $val"
21217 }
21218 run_test 230m "xattrs not changed after dir migration"
21219
21220 test_230n() {
21221         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21222         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21223                 skip "Need MDS version at least 2.13.53"
21224
21225         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21226         cat /etc/hosts > $DIR/$tdir/$tfile
21227         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21228         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21229
21230         cmp /etc/hosts $DIR/$tdir/$tfile ||
21231                 error "File data mismatch after migration"
21232 }
21233 run_test 230n "Dir migration with mirrored file"
21234
21235 test_230o() {
21236         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21237         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21238                 skip "Need MDS version at least 2.13.52"
21239
21240         local mdts=$(comma_list $(mdts_nodes))
21241         local timeout=100
21242         local restripe_status
21243         local delta
21244         local i
21245
21246         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21247
21248         # in case "crush" hash type is not set
21249         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21250
21251         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21252                            mdt.*MDT0000.enable_dir_restripe)
21253         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21254         stack_trap "do_nodes $mdts $LCTL set_param \
21255                     mdt.*.enable_dir_restripe=$restripe_status"
21256
21257         mkdir $DIR/$tdir
21258         createmany -m $DIR/$tdir/f 100 ||
21259                 error "create files under remote dir failed $i"
21260         createmany -d $DIR/$tdir/d 100 ||
21261                 error "create dirs under remote dir failed $i"
21262
21263         for i in $(seq 2 $MDSCOUNT); do
21264                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21265                 $LFS setdirstripe -c $i $DIR/$tdir ||
21266                         error "split -c $i $tdir failed"
21267                 wait_update $HOSTNAME \
21268                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21269                         error "dir split not finished"
21270                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21271                         awk '/migrate/ {sum += $2} END { print sum }')
21272                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21273                 # delta is around total_files/stripe_count
21274                 (( $delta < 200 / (i - 1) + 4 )) ||
21275                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21276         done
21277 }
21278 run_test 230o "dir split"
21279
21280 test_230p() {
21281         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21282         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21283                 skip "Need MDS version at least 2.13.52"
21284
21285         local mdts=$(comma_list $(mdts_nodes))
21286         local timeout=100
21287         local restripe_status
21288         local delta
21289         local c
21290
21291         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21292
21293         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21294
21295         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21296                            mdt.*MDT0000.enable_dir_restripe)
21297         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21298         stack_trap "do_nodes $mdts $LCTL set_param \
21299                     mdt.*.enable_dir_restripe=$restripe_status"
21300
21301         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21302         createmany -m $DIR/$tdir/f 100 ||
21303                 error "create files under remote dir failed"
21304         createmany -d $DIR/$tdir/d 100 ||
21305                 error "create dirs under remote dir failed"
21306
21307         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21308                 local mdt_hash="crush"
21309
21310                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21311                 $LFS setdirstripe -c $c $DIR/$tdir ||
21312                         error "split -c $c $tdir failed"
21313                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21314                         mdt_hash="$mdt_hash,fixed"
21315                 elif [ $c -eq 1 ]; then
21316                         mdt_hash="none"
21317                 fi
21318                 wait_update $HOSTNAME \
21319                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21320                         error "dir merge not finished"
21321                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21322                         awk '/migrate/ {sum += $2} END { print sum }')
21323                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21324                 # delta is around total_files/stripe_count
21325                 (( delta < 200 / c + 4 )) ||
21326                         error "$delta files migrated >= $((200 / c + 4))"
21327         done
21328 }
21329 run_test 230p "dir merge"
21330
21331 test_230q() {
21332         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21333         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21334                 skip "Need MDS version at least 2.13.52"
21335
21336         local mdts=$(comma_list $(mdts_nodes))
21337         local saved_threshold=$(do_facet mds1 \
21338                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21339         local saved_delta=$(do_facet mds1 \
21340                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21341         local threshold=100
21342         local delta=2
21343         local total=0
21344         local stripe_count=0
21345         local stripe_index
21346         local nr_files
21347         local create
21348
21349         # test with fewer files on ZFS
21350         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21351
21352         stack_trap "do_nodes $mdts $LCTL set_param \
21353                     mdt.*.dir_split_count=$saved_threshold"
21354         stack_trap "do_nodes $mdts $LCTL set_param \
21355                     mdt.*.dir_split_delta=$saved_delta"
21356         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21357         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21358         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21359         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21360         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21361         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21362
21363         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21364         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21365
21366         create=$((threshold * 3 / 2))
21367         while [ $stripe_count -lt $MDSCOUNT ]; do
21368                 createmany -m $DIR/$tdir/f $total $create ||
21369                         error "create sub files failed"
21370                 stat $DIR/$tdir > /dev/null
21371                 total=$((total + create))
21372                 stripe_count=$((stripe_count + delta))
21373                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21374
21375                 wait_update $HOSTNAME \
21376                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21377                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21378
21379                 wait_update $HOSTNAME \
21380                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21381                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21382
21383                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21384                 echo "$nr_files/$total files on MDT$stripe_index after split"
21385                 # allow 10% margin of imbalance with crush hash
21386                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21387                         error "$nr_files files on MDT$stripe_index after split"
21388
21389                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21390                 [ $nr_files -eq $total ] ||
21391                         error "total sub files $nr_files != $total"
21392         done
21393
21394         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21395
21396         echo "fixed layout directory won't auto split"
21397         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21398         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21399                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21400         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21401                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21402 }
21403 run_test 230q "dir auto split"
21404
21405 test_230r() {
21406         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21407         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21408         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21409                 skip "Need MDS version at least 2.13.54"
21410
21411         # maximum amount of local locks:
21412         # parent striped dir - 2 locks
21413         # new stripe in parent to migrate to - 1 lock
21414         # source and target - 2 locks
21415         # Total 5 locks for regular file
21416         mkdir -p $DIR/$tdir
21417         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21418         touch $DIR/$tdir/dir1/eee
21419
21420         # create 4 hardlink for 4 more locks
21421         # Total: 9 locks > RS_MAX_LOCKS (8)
21422         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21423         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21424         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21425         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21426         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21427         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21428         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21429         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21430
21431         cancel_lru_locks mdc
21432
21433         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21434                 error "migrate dir fails"
21435
21436         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21437 }
21438 run_test 230r "migrate with too many local locks"
21439
21440 test_230s() {
21441         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21442                 skip "Need MDS version at least 2.14.52"
21443
21444         local mdts=$(comma_list $(mdts_nodes))
21445         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21446                                 mdt.*MDT0000.enable_dir_restripe)
21447
21448         stack_trap "do_nodes $mdts $LCTL set_param \
21449                     mdt.*.enable_dir_restripe=$restripe_status"
21450
21451         local st
21452         for st in 0 1; do
21453                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21454                 test_mkdir $DIR/$tdir
21455                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21456                         error "$LFS mkdir should return EEXIST if target exists"
21457                 rmdir $DIR/$tdir
21458         done
21459 }
21460 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21461
21462 test_230t()
21463 {
21464         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21465         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21466                 skip "Need MDS version at least 2.14.50"
21467
21468         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21469         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21470         $LFS project -p 1 -s $DIR/$tdir ||
21471                 error "set $tdir project id failed"
21472         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21473                 error "set subdir project id failed"
21474         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21475 }
21476 run_test 230t "migrate directory with project ID set"
21477
21478 test_230u()
21479 {
21480         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21481         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21482                 skip "Need MDS version at least 2.14.53"
21483
21484         local count
21485
21486         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21487         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21488         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21489         for i in $(seq 0 $((MDSCOUNT - 1))); do
21490                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21491                 echo "$count dirs migrated to MDT$i"
21492         done
21493         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21494         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21495 }
21496 run_test 230u "migrate directory by QOS"
21497
21498 test_230v()
21499 {
21500         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21501         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21502                 skip "Need MDS version at least 2.14.53"
21503
21504         local count
21505
21506         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21507         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21508         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21509         for i in $(seq 0 $((MDSCOUNT - 1))); do
21510                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21511                 echo "$count subdirs migrated to MDT$i"
21512                 (( i == 3 )) && (( count > 0 )) &&
21513                         error "subdir shouldn't be migrated to MDT3"
21514         done
21515         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21516         (( count == 3 )) || error "dirs migrated to $count MDTs"
21517 }
21518 run_test 230v "subdir migrated to the MDT where its parent is located"
21519
21520 test_230w() {
21521         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21522         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21523                 skip "Need MDS version at least 2.15.0"
21524
21525         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21526         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21527         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21528
21529         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21530                 error "migrate failed"
21531
21532         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21533                 error "$tdir stripe count mismatch"
21534
21535         for i in $(seq 0 9); do
21536                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21537                         error "d$i is striped"
21538         done
21539 }
21540 run_test 230w "non-recursive mode dir migration"
21541
21542 test_230x() {
21543         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21544         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21545                 skip "Need MDS version at least 2.15.0"
21546
21547         mkdir -p $DIR/$tdir || error "mkdir failed"
21548         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21549
21550         local mdt_name=$(mdtname_from_index 0)
21551         local low=$(do_facet mds2 $LCTL get_param -n \
21552                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21553         local high=$(do_facet mds2 $LCTL get_param -n \
21554                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21555         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21556         local maxage=$(do_facet mds2 $LCTL get_param -n \
21557                 osp.*$mdt_name-osp-MDT0001.maxage)
21558
21559         stack_trap "do_facet mds2 $LCTL set_param -n \
21560                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21561                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21562         stack_trap "do_facet mds2 $LCTL set_param -n \
21563                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21564
21565         do_facet mds2 $LCTL set_param -n \
21566                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21567         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21568         sleep 4
21569         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21570                 error "migrate $tdir should fail"
21571
21572         do_facet mds2 $LCTL set_param -n \
21573                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21574         do_facet mds2 $LCTL set_param -n \
21575                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21576         sleep 4
21577         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21578                 error "migrate failed"
21579         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21580                 error "$tdir stripe count mismatch"
21581 }
21582 run_test 230x "dir migration check space"
21583
21584 test_231a()
21585 {
21586         # For simplicity this test assumes that max_pages_per_rpc
21587         # is the same across all OSCs
21588         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21589         local bulk_size=$((max_pages * PAGE_SIZE))
21590         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21591                                        head -n 1)
21592
21593         mkdir -p $DIR/$tdir
21594         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21595                 error "failed to set stripe with -S ${brw_size}M option"
21596
21597         # clear the OSC stats
21598         $LCTL set_param osc.*.stats=0 &>/dev/null
21599         stop_writeback
21600
21601         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21602         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21603                 oflag=direct &>/dev/null || error "dd failed"
21604
21605         sync; sleep 1; sync # just to be safe
21606         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21607         if [ x$nrpcs != "x1" ]; then
21608                 $LCTL get_param osc.*.stats
21609                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21610         fi
21611
21612         start_writeback
21613         # Drop the OSC cache, otherwise we will read from it
21614         cancel_lru_locks osc
21615
21616         # clear the OSC stats
21617         $LCTL set_param osc.*.stats=0 &>/dev/null
21618
21619         # Client reads $bulk_size.
21620         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21621                 iflag=direct &>/dev/null || error "dd failed"
21622
21623         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21624         if [ x$nrpcs != "x1" ]; then
21625                 $LCTL get_param osc.*.stats
21626                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21627         fi
21628 }
21629 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21630
21631 test_231b() {
21632         mkdir -p $DIR/$tdir
21633         local i
21634         for i in {0..1023}; do
21635                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21636                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21637                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21638         done
21639         sync
21640 }
21641 run_test 231b "must not assert on fully utilized OST request buffer"
21642
21643 test_232a() {
21644         mkdir -p $DIR/$tdir
21645         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21646
21647         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21648         do_facet ost1 $LCTL set_param fail_loc=0x31c
21649
21650         # ignore dd failure
21651         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21652
21653         do_facet ost1 $LCTL set_param fail_loc=0
21654         umount_client $MOUNT || error "umount failed"
21655         mount_client $MOUNT || error "mount failed"
21656         stop ost1 || error "cannot stop ost1"
21657         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21658 }
21659 run_test 232a "failed lock should not block umount"
21660
21661 test_232b() {
21662         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21663                 skip "Need MDS version at least 2.10.58"
21664
21665         mkdir -p $DIR/$tdir
21666         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21667         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21668         sync
21669         cancel_lru_locks osc
21670
21671         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21672         do_facet ost1 $LCTL set_param fail_loc=0x31c
21673
21674         # ignore failure
21675         $LFS data_version $DIR/$tdir/$tfile || true
21676
21677         do_facet ost1 $LCTL set_param fail_loc=0
21678         umount_client $MOUNT || error "umount failed"
21679         mount_client $MOUNT || error "mount failed"
21680         stop ost1 || error "cannot stop ost1"
21681         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21682 }
21683 run_test 232b "failed data version lock should not block umount"
21684
21685 test_233a() {
21686         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21687                 skip "Need MDS version at least 2.3.64"
21688         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21689
21690         local fid=$($LFS path2fid $MOUNT)
21691
21692         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21693                 error "cannot access $MOUNT using its FID '$fid'"
21694 }
21695 run_test 233a "checking that OBF of the FS root succeeds"
21696
21697 test_233b() {
21698         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21699                 skip "Need MDS version at least 2.5.90"
21700         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21701
21702         local fid=$($LFS path2fid $MOUNT/.lustre)
21703
21704         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21705                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21706
21707         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21708         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21709                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21710 }
21711 run_test 233b "checking that OBF of the FS .lustre succeeds"
21712
21713 test_234() {
21714         local p="$TMP/sanityN-$TESTNAME.parameters"
21715         save_lustre_params client "llite.*.xattr_cache" > $p
21716         lctl set_param llite.*.xattr_cache 1 ||
21717                 skip_env "xattr cache is not supported"
21718
21719         mkdir -p $DIR/$tdir || error "mkdir failed"
21720         touch $DIR/$tdir/$tfile || error "touch failed"
21721         # OBD_FAIL_LLITE_XATTR_ENOMEM
21722         $LCTL set_param fail_loc=0x1405
21723         getfattr -n user.attr $DIR/$tdir/$tfile &&
21724                 error "getfattr should have failed with ENOMEM"
21725         $LCTL set_param fail_loc=0x0
21726         rm -rf $DIR/$tdir
21727
21728         restore_lustre_params < $p
21729         rm -f $p
21730 }
21731 run_test 234 "xattr cache should not crash on ENOMEM"
21732
21733 test_235() {
21734         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21735                 skip "Need MDS version at least 2.4.52"
21736
21737         flock_deadlock $DIR/$tfile
21738         local RC=$?
21739         case $RC in
21740                 0)
21741                 ;;
21742                 124) error "process hangs on a deadlock"
21743                 ;;
21744                 *) error "error executing flock_deadlock $DIR/$tfile"
21745                 ;;
21746         esac
21747 }
21748 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21749
21750 #LU-2935
21751 test_236() {
21752         check_swap_layouts_support
21753
21754         local ref1=/etc/passwd
21755         local ref2=/etc/group
21756         local file1=$DIR/$tdir/f1
21757         local file2=$DIR/$tdir/f2
21758
21759         test_mkdir -c1 $DIR/$tdir
21760         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21761         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21762         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21763         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21764         local fd=$(free_fd)
21765         local cmd="exec $fd<>$file2"
21766         eval $cmd
21767         rm $file2
21768         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21769                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21770         cmd="exec $fd>&-"
21771         eval $cmd
21772         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21773
21774         #cleanup
21775         rm -rf $DIR/$tdir
21776 }
21777 run_test 236 "Layout swap on open unlinked file"
21778
21779 # LU-4659 linkea consistency
21780 test_238() {
21781         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21782                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21783                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21784                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21785
21786         touch $DIR/$tfile
21787         ln $DIR/$tfile $DIR/$tfile.lnk
21788         touch $DIR/$tfile.new
21789         mv $DIR/$tfile.new $DIR/$tfile
21790         local fid1=$($LFS path2fid $DIR/$tfile)
21791         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21792         local path1=$($LFS fid2path $FSNAME "$fid1")
21793         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21794         local path2=$($LFS fid2path $FSNAME "$fid2")
21795         [ $tfile.lnk == $path2 ] ||
21796                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21797         rm -f $DIR/$tfile*
21798 }
21799 run_test 238 "Verify linkea consistency"
21800
21801 test_239A() { # was test_239
21802         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21803                 skip "Need MDS version at least 2.5.60"
21804
21805         local list=$(comma_list $(mdts_nodes))
21806
21807         mkdir -p $DIR/$tdir
21808         createmany -o $DIR/$tdir/f- 5000
21809         unlinkmany $DIR/$tdir/f- 5000
21810         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21811                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21812         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21813                         osp.*MDT*.sync_in_flight" | calc_sum)
21814         [ "$changes" -eq 0 ] || error "$changes not synced"
21815 }
21816 run_test 239A "osp_sync test"
21817
21818 test_239a() { #LU-5297
21819         remote_mds_nodsh && skip "remote MDS with nodsh"
21820
21821         touch $DIR/$tfile
21822         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21823         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21824         chgrp $RUNAS_GID $DIR/$tfile
21825         wait_delete_completed
21826 }
21827 run_test 239a "process invalid osp sync record correctly"
21828
21829 test_239b() { #LU-5297
21830         remote_mds_nodsh && skip "remote MDS with nodsh"
21831
21832         touch $DIR/$tfile1
21833         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21834         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21835         chgrp $RUNAS_GID $DIR/$tfile1
21836         wait_delete_completed
21837         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21838         touch $DIR/$tfile2
21839         chgrp $RUNAS_GID $DIR/$tfile2
21840         wait_delete_completed
21841 }
21842 run_test 239b "process osp sync record with ENOMEM error correctly"
21843
21844 test_240() {
21845         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21846         remote_mds_nodsh && skip "remote MDS with nodsh"
21847
21848         mkdir -p $DIR/$tdir
21849
21850         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21851                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21852         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21853                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21854
21855         umount_client $MOUNT || error "umount failed"
21856         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21857         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21858         mount_client $MOUNT || error "failed to mount client"
21859
21860         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21861         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21862 }
21863 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21864
21865 test_241_bio() {
21866         local count=$1
21867         local bsize=$2
21868
21869         for LOOP in $(seq $count); do
21870                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21871                 cancel_lru_locks $OSC || true
21872         done
21873 }
21874
21875 test_241_dio() {
21876         local count=$1
21877         local bsize=$2
21878
21879         for LOOP in $(seq $1); do
21880                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21881                         2>/dev/null
21882         done
21883 }
21884
21885 test_241a() { # was test_241
21886         local bsize=$PAGE_SIZE
21887
21888         (( bsize < 40960 )) && bsize=40960
21889         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21890         ls -la $DIR/$tfile
21891         cancel_lru_locks $OSC
21892         test_241_bio 1000 $bsize &
21893         PID=$!
21894         test_241_dio 1000 $bsize
21895         wait $PID
21896 }
21897 run_test 241a "bio vs dio"
21898
21899 test_241b() {
21900         local bsize=$PAGE_SIZE
21901
21902         (( bsize < 40960 )) && bsize=40960
21903         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21904         ls -la $DIR/$tfile
21905         test_241_dio 1000 $bsize &
21906         PID=$!
21907         test_241_dio 1000 $bsize
21908         wait $PID
21909 }
21910 run_test 241b "dio vs dio"
21911
21912 test_242() {
21913         remote_mds_nodsh && skip "remote MDS with nodsh"
21914
21915         mkdir_on_mdt0 $DIR/$tdir
21916         touch $DIR/$tdir/$tfile
21917
21918         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21919         do_facet mds1 lctl set_param fail_loc=0x105
21920         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21921
21922         do_facet mds1 lctl set_param fail_loc=0
21923         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21924 }
21925 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21926
21927 test_243()
21928 {
21929         test_mkdir $DIR/$tdir
21930         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21931 }
21932 run_test 243 "various group lock tests"
21933
21934 test_244a()
21935 {
21936         test_mkdir $DIR/$tdir
21937         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21938         sendfile_grouplock $DIR/$tdir/$tfile || \
21939                 error "sendfile+grouplock failed"
21940         rm -rf $DIR/$tdir
21941 }
21942 run_test 244a "sendfile with group lock tests"
21943
21944 test_244b()
21945 {
21946         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21947
21948         local threads=50
21949         local size=$((1024*1024))
21950
21951         test_mkdir $DIR/$tdir
21952         for i in $(seq 1 $threads); do
21953                 local file=$DIR/$tdir/file_$((i / 10))
21954                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21955                 local pids[$i]=$!
21956         done
21957         for i in $(seq 1 $threads); do
21958                 wait ${pids[$i]}
21959         done
21960 }
21961 run_test 244b "multi-threaded write with group lock"
21962
21963 test_245a() {
21964         local flagname="multi_mod_rpcs"
21965         local connect_data_name="max_mod_rpcs"
21966         local out
21967
21968         # check if multiple modify RPCs flag is set
21969         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21970                 grep "connect_flags:")
21971         echo "$out"
21972
21973         echo "$out" | grep -qw $flagname
21974         if [ $? -ne 0 ]; then
21975                 echo "connect flag $flagname is not set"
21976                 return
21977         fi
21978
21979         # check if multiple modify RPCs data is set
21980         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21981         echo "$out"
21982
21983         echo "$out" | grep -qw $connect_data_name ||
21984                 error "import should have connect data $connect_data_name"
21985 }
21986 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21987
21988 test_245b() {
21989         local flagname="multi_mod_rpcs"
21990         local connect_data_name="max_mod_rpcs"
21991         local out
21992
21993         remote_mds_nodsh && skip "remote MDS with nodsh"
21994         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21995
21996         # check if multiple modify RPCs flag is set
21997         out=$(do_facet mds1 \
21998               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21999               grep "connect_flags:")
22000         echo "$out"
22001
22002         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22003
22004         # check if multiple modify RPCs data is set
22005         out=$(do_facet mds1 \
22006               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22007
22008         [[ "$out" =~ $connect_data_name ]] ||
22009                 {
22010                         echo "$out"
22011                         error "missing connect data $connect_data_name"
22012                 }
22013 }
22014 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22015
22016 cleanup_247() {
22017         local submount=$1
22018
22019         trap 0
22020         umount_client $submount
22021         rmdir $submount
22022 }
22023
22024 test_247a() {
22025         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22026                 grep -q subtree ||
22027                 skip_env "Fileset feature is not supported"
22028
22029         local submount=${MOUNT}_$tdir
22030
22031         mkdir $MOUNT/$tdir
22032         mkdir -p $submount || error "mkdir $submount failed"
22033         FILESET="$FILESET/$tdir" mount_client $submount ||
22034                 error "mount $submount failed"
22035         trap "cleanup_247 $submount" EXIT
22036         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22037         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22038                 error "read $MOUNT/$tdir/$tfile failed"
22039         cleanup_247 $submount
22040 }
22041 run_test 247a "mount subdir as fileset"
22042
22043 test_247b() {
22044         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22045                 skip_env "Fileset feature is not supported"
22046
22047         local submount=${MOUNT}_$tdir
22048
22049         rm -rf $MOUNT/$tdir
22050         mkdir -p $submount || error "mkdir $submount failed"
22051         SKIP_FILESET=1
22052         FILESET="$FILESET/$tdir" mount_client $submount &&
22053                 error "mount $submount should fail"
22054         rmdir $submount
22055 }
22056 run_test 247b "mount subdir that dose not exist"
22057
22058 test_247c() {
22059         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22060                 skip_env "Fileset feature is not supported"
22061
22062         local submount=${MOUNT}_$tdir
22063
22064         mkdir -p $MOUNT/$tdir/dir1
22065         mkdir -p $submount || error "mkdir $submount failed"
22066         trap "cleanup_247 $submount" EXIT
22067         FILESET="$FILESET/$tdir" mount_client $submount ||
22068                 error "mount $submount failed"
22069         local fid=$($LFS path2fid $MOUNT/)
22070         $LFS fid2path $submount $fid && error "fid2path should fail"
22071         cleanup_247 $submount
22072 }
22073 run_test 247c "running fid2path outside subdirectory root"
22074
22075 test_247d() {
22076         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22077                 skip "Fileset feature is not supported"
22078
22079         local submount=${MOUNT}_$tdir
22080
22081         mkdir -p $MOUNT/$tdir/dir1
22082         mkdir -p $submount || error "mkdir $submount failed"
22083         FILESET="$FILESET/$tdir" mount_client $submount ||
22084                 error "mount $submount failed"
22085         trap "cleanup_247 $submount" EXIT
22086
22087         local td=$submount/dir1
22088         local fid=$($LFS path2fid $td)
22089         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22090
22091         # check that we get the same pathname back
22092         local rootpath
22093         local found
22094         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22095                 echo "$rootpath $fid"
22096                 found=$($LFS fid2path $rootpath "$fid")
22097                 [ -n "$found" ] || error "fid2path should succeed"
22098                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22099         done
22100         # check wrong root path format
22101         rootpath=$submount"_wrong"
22102         found=$($LFS fid2path $rootpath "$fid")
22103         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22104
22105         cleanup_247 $submount
22106 }
22107 run_test 247d "running fid2path inside subdirectory root"
22108
22109 # LU-8037
22110 test_247e() {
22111         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22112                 grep -q subtree ||
22113                 skip "Fileset feature is not supported"
22114
22115         local submount=${MOUNT}_$tdir
22116
22117         mkdir $MOUNT/$tdir
22118         mkdir -p $submount || error "mkdir $submount failed"
22119         FILESET="$FILESET/.." mount_client $submount &&
22120                 error "mount $submount should fail"
22121         rmdir $submount
22122 }
22123 run_test 247e "mount .. as fileset"
22124
22125 test_247f() {
22126         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22127         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22128                 skip "Need at least version 2.14.50.162"
22129         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22130                 skip "Fileset feature is not supported"
22131
22132         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22133         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22134                 error "mkdir remote failed"
22135         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22136                 error "mkdir remote/subdir failed"
22137         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22138                 error "mkdir striped failed"
22139         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22140
22141         local submount=${MOUNT}_$tdir
22142
22143         mkdir -p $submount || error "mkdir $submount failed"
22144         stack_trap "rmdir $submount"
22145
22146         local dir
22147         local fileset=$FILESET
22148         local mdts=$(comma_list $(mdts_nodes))
22149
22150         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22151         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22152                 $tdir/striped/subdir $tdir/striped/.; do
22153                 FILESET="$fileset/$dir" mount_client $submount ||
22154                         error "mount $dir failed"
22155                 umount_client $submount
22156         done
22157 }
22158 run_test 247f "mount striped or remote directory as fileset"
22159
22160 test_subdir_mount_lock()
22161 {
22162         local testdir=$1
22163         local submount=${MOUNT}_$(basename $testdir)
22164
22165         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22166
22167         mkdir -p $submount || error "mkdir $submount failed"
22168         stack_trap "rmdir $submount"
22169
22170         FILESET="$fileset/$testdir" mount_client $submount ||
22171                 error "mount $FILESET failed"
22172         stack_trap "umount $submount"
22173
22174         local mdts=$(comma_list $(mdts_nodes))
22175
22176         local nrpcs
22177
22178         stat $submount > /dev/null || error "stat $submount failed"
22179         cancel_lru_locks $MDC
22180         stat $submount > /dev/null || error "stat $submount failed"
22181         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22182         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22183         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22184         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22185                 awk '/getattr/ {sum += $2} END {print sum}')
22186
22187         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22188 }
22189
22190 test_247g() {
22191         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22192
22193         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22194                 error "mkdir $tdir failed"
22195         test_subdir_mount_lock $tdir
22196 }
22197 run_test 247g "striped directory submount revalidate ROOT from cache"
22198
22199 test_247h() {
22200         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22201         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22202                 skip "Need MDS version at least 2.15.51"
22203
22204         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22205         test_subdir_mount_lock $tdir
22206         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22207         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22208                 error "mkdir $tdir.1 failed"
22209         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22210 }
22211 run_test 247h "remote directory submount revalidate ROOT from cache"
22212
22213 test_248a() {
22214         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22215         [ -z "$fast_read_sav" ] && skip "no fast read support"
22216
22217         # create a large file for fast read verification
22218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22219
22220         # make sure the file is created correctly
22221         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22222                 { rm -f $DIR/$tfile; skip "file creation error"; }
22223
22224         echo "Test 1: verify that fast read is 4 times faster on cache read"
22225
22226         # small read with fast read enabled
22227         $LCTL set_param -n llite.*.fast_read=1
22228         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22229                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22230                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22231         # small read with fast read disabled
22232         $LCTL set_param -n llite.*.fast_read=0
22233         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22234                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22235                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22236
22237         # verify that fast read is 4 times faster for cache read
22238         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22239                 error_not_in_vm "fast read was not 4 times faster: " \
22240                            "$t_fast vs $t_slow"
22241
22242         echo "Test 2: verify the performance between big and small read"
22243         $LCTL set_param -n llite.*.fast_read=1
22244
22245         # 1k non-cache read
22246         cancel_lru_locks osc
22247         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22248                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22249                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22250
22251         # 1M non-cache read
22252         cancel_lru_locks osc
22253         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22254                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22255                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22256
22257         # verify that big IO is not 4 times faster than small IO
22258         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22259                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22260
22261         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22262         rm -f $DIR/$tfile
22263 }
22264 run_test 248a "fast read verification"
22265
22266 test_248b() {
22267         # Default short_io_bytes=16384, try both smaller and larger sizes.
22268         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22269         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22270         echo "bs=53248 count=113 normal buffered write"
22271         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22272                 error "dd of initial data file failed"
22273         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22274
22275         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22276         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22277                 error "dd with sync normal writes failed"
22278         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22279
22280         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22281         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22282                 error "dd with sync small writes failed"
22283         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22284
22285         cancel_lru_locks osc
22286
22287         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22288         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22289         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22290         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22291                 iflag=direct || error "dd with O_DIRECT small read failed"
22292         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22293         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22294                 error "compare $TMP/$tfile.1 failed"
22295
22296         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22297         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22298
22299         # just to see what the maximum tunable value is, and test parsing
22300         echo "test invalid parameter 2MB"
22301         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22302                 error "too-large short_io_bytes allowed"
22303         echo "test maximum parameter 512KB"
22304         # if we can set a larger short_io_bytes, run test regardless of version
22305         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22306                 # older clients may not allow setting it this large, that's OK
22307                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22308                         skip "Need at least client version 2.13.50"
22309                 error "medium short_io_bytes failed"
22310         fi
22311         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22312         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22313
22314         echo "test large parameter 64KB"
22315         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22316         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22317
22318         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22319         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22320                 error "dd with sync large writes failed"
22321         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22322
22323         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22324         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22325         num=$((113 * 4096 / PAGE_SIZE))
22326         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22327         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22328                 error "dd with O_DIRECT large writes failed"
22329         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22330                 error "compare $DIR/$tfile.3 failed"
22331
22332         cancel_lru_locks osc
22333
22334         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22335         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22336                 error "dd with O_DIRECT large read failed"
22337         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22338                 error "compare $TMP/$tfile.2 failed"
22339
22340         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22341         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22342                 error "dd with O_DIRECT large read failed"
22343         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22344                 error "compare $TMP/$tfile.3 failed"
22345 }
22346 run_test 248b "test short_io read and write for both small and large sizes"
22347
22348 test_249() { # LU-7890
22349         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22350                 skip "Need at least version 2.8.54"
22351
22352         rm -f $DIR/$tfile
22353         $LFS setstripe -c 1 $DIR/$tfile
22354         # Offset 2T == 4k * 512M
22355         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22356                 error "dd to 2T offset failed"
22357 }
22358 run_test 249 "Write above 2T file size"
22359
22360 test_250() {
22361         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22362          && skip "no 16TB file size limit on ZFS"
22363
22364         $LFS setstripe -c 1 $DIR/$tfile
22365         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22366         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22367         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22368         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22369                 conv=notrunc,fsync && error "append succeeded"
22370         return 0
22371 }
22372 run_test 250 "Write above 16T limit"
22373
22374 test_251() {
22375         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22376
22377         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22378         #Skip once - writing the first stripe will succeed
22379         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22380         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22381                 error "short write happened"
22382
22383         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22384         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22385                 error "short read happened"
22386
22387         rm -f $DIR/$tfile
22388 }
22389 run_test 251 "Handling short read and write correctly"
22390
22391 test_252() {
22392         remote_mds_nodsh && skip "remote MDS with nodsh"
22393         remote_ost_nodsh && skip "remote OST with nodsh"
22394         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22395                 skip_env "ldiskfs only test"
22396         fi
22397
22398         local tgt
22399         local dev
22400         local out
22401         local uuid
22402         local num
22403         local gen
22404
22405         # check lr_reader on OST0000
22406         tgt=ost1
22407         dev=$(facet_device $tgt)
22408         out=$(do_facet $tgt $LR_READER $dev)
22409         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22410         echo "$out"
22411         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22412         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22413                 error "Invalid uuid returned by $LR_READER on target $tgt"
22414         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22415
22416         # check lr_reader -c on MDT0000
22417         tgt=mds1
22418         dev=$(facet_device $tgt)
22419         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22420                 skip "$LR_READER does not support additional options"
22421         fi
22422         out=$(do_facet $tgt $LR_READER -c $dev)
22423         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22424         echo "$out"
22425         num=$(echo "$out" | grep -c "mdtlov")
22426         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22427                 error "Invalid number of mdtlov clients returned by $LR_READER"
22428         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22429
22430         # check lr_reader -cr on MDT0000
22431         out=$(do_facet $tgt $LR_READER -cr $dev)
22432         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22433         echo "$out"
22434         echo "$out" | grep -q "^reply_data:$" ||
22435                 error "$LR_READER should have returned 'reply_data' section"
22436         num=$(echo "$out" | grep -c "client_generation")
22437         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22438 }
22439 run_test 252 "check lr_reader tool"
22440
22441 test_253() {
22442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22443         remote_mds_nodsh && skip "remote MDS with nodsh"
22444         remote_mgs_nodsh && skip "remote MGS with nodsh"
22445
22446         local ostidx=0
22447         local rc=0
22448         local ost_name=$(ostname_from_index $ostidx)
22449
22450         # on the mdt's osc
22451         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22452         do_facet $SINGLEMDS $LCTL get_param -n \
22453                 osp.$mdtosc_proc1.reserved_mb_high ||
22454                 skip  "remote MDS does not support reserved_mb_high"
22455
22456         rm -rf $DIR/$tdir
22457         wait_mds_ost_sync
22458         wait_delete_completed
22459         mkdir $DIR/$tdir
22460
22461         pool_add $TESTNAME || error "Pool creation failed"
22462         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22463
22464         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22465                 error "Setstripe failed"
22466
22467         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22468
22469         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22470                     grep "watermarks")
22471         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22472
22473         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22474                         osp.$mdtosc_proc1.prealloc_status)
22475         echo "prealloc_status $oa_status"
22476
22477         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22478                 error "File creation should fail"
22479
22480         #object allocation was stopped, but we still able to append files
22481         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22482                 oflag=append || error "Append failed"
22483
22484         rm -f $DIR/$tdir/$tfile.0
22485
22486         # For this test, we want to delete the files we created to go out of
22487         # space but leave the watermark, so we remain nearly out of space
22488         ost_watermarks_enospc_delete_files $tfile $ostidx
22489
22490         wait_delete_completed
22491
22492         sleep_maxage
22493
22494         for i in $(seq 10 12); do
22495                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22496                         2>/dev/null || error "File creation failed after rm"
22497         done
22498
22499         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22500                         osp.$mdtosc_proc1.prealloc_status)
22501         echo "prealloc_status $oa_status"
22502
22503         if (( oa_status != 0 )); then
22504                 error "Object allocation still disable after rm"
22505         fi
22506 }
22507 run_test 253 "Check object allocation limit"
22508
22509 test_254() {
22510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22511         remote_mds_nodsh && skip "remote MDS with nodsh"
22512
22513         local mdt=$(facet_svc $SINGLEMDS)
22514
22515         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22516                 skip "MDS does not support changelog_size"
22517
22518         local cl_user
22519
22520         changelog_register || error "changelog_register failed"
22521
22522         changelog_clear 0 || error "changelog_clear failed"
22523
22524         local size1=$(do_facet $SINGLEMDS \
22525                       $LCTL get_param -n mdd.$mdt.changelog_size)
22526         echo "Changelog size $size1"
22527
22528         rm -rf $DIR/$tdir
22529         $LFS mkdir -i 0 $DIR/$tdir
22530         # change something
22531         mkdir -p $DIR/$tdir/pics/2008/zachy
22532         touch $DIR/$tdir/pics/2008/zachy/timestamp
22533         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22534         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22535         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22536         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22537         rm $DIR/$tdir/pics/desktop.jpg
22538
22539         local size2=$(do_facet $SINGLEMDS \
22540                       $LCTL get_param -n mdd.$mdt.changelog_size)
22541         echo "Changelog size after work $size2"
22542
22543         (( $size2 > $size1 )) ||
22544                 error "new Changelog size=$size2 less than old size=$size1"
22545 }
22546 run_test 254 "Check changelog size"
22547
22548 ladvise_no_type()
22549 {
22550         local type=$1
22551         local file=$2
22552
22553         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22554                 awk -F: '{print $2}' | grep $type > /dev/null
22555         if [ $? -ne 0 ]; then
22556                 return 0
22557         fi
22558         return 1
22559 }
22560
22561 ladvise_no_ioctl()
22562 {
22563         local file=$1
22564
22565         lfs ladvise -a willread $file > /dev/null 2>&1
22566         if [ $? -eq 0 ]; then
22567                 return 1
22568         fi
22569
22570         lfs ladvise -a willread $file 2>&1 |
22571                 grep "Inappropriate ioctl for device" > /dev/null
22572         if [ $? -eq 0 ]; then
22573                 return 0
22574         fi
22575         return 1
22576 }
22577
22578 percent() {
22579         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22580 }
22581
22582 # run a random read IO workload
22583 # usage: random_read_iops <filename> <filesize> <iosize>
22584 random_read_iops() {
22585         local file=$1
22586         local fsize=$2
22587         local iosize=${3:-4096}
22588
22589         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22590                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22591 }
22592
22593 drop_file_oss_cache() {
22594         local file="$1"
22595         local nodes="$2"
22596
22597         $LFS ladvise -a dontneed $file 2>/dev/null ||
22598                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22599 }
22600
22601 ladvise_willread_performance()
22602 {
22603         local repeat=10
22604         local average_origin=0
22605         local average_cache=0
22606         local average_ladvise=0
22607
22608         for ((i = 1; i <= $repeat; i++)); do
22609                 echo "Iter $i/$repeat: reading without willread hint"
22610                 cancel_lru_locks osc
22611                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22612                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22613                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22614                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22615
22616                 cancel_lru_locks osc
22617                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22618                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22619                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22620
22621                 cancel_lru_locks osc
22622                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22623                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22624                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22625                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22626                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22627         done
22628         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22629         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22630         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22631
22632         speedup_cache=$(percent $average_cache $average_origin)
22633         speedup_ladvise=$(percent $average_ladvise $average_origin)
22634
22635         echo "Average uncached read: $average_origin"
22636         echo "Average speedup with OSS cached read: " \
22637                 "$average_cache = +$speedup_cache%"
22638         echo "Average speedup with ladvise willread: " \
22639                 "$average_ladvise = +$speedup_ladvise%"
22640
22641         local lowest_speedup=20
22642         if (( ${average_cache%.*} < $lowest_speedup )); then
22643                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22644                      " got $average_cache%. Skipping ladvise willread check."
22645                 return 0
22646         fi
22647
22648         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22649         # it is still good to run until then to exercise 'ladvise willread'
22650         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22651                 [ "$ost1_FSTYPE" = "zfs" ] &&
22652                 echo "osd-zfs does not support dontneed or drop_caches" &&
22653                 return 0
22654
22655         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22656         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22657                 error_not_in_vm "Speedup with willread is less than " \
22658                         "$lowest_speedup%, got $average_ladvise%"
22659 }
22660
22661 test_255a() {
22662         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22663                 skip "lustre < 2.8.54 does not support ladvise "
22664         remote_ost_nodsh && skip "remote OST with nodsh"
22665
22666         stack_trap "rm -f $DIR/$tfile"
22667         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22668
22669         ladvise_no_type willread $DIR/$tfile &&
22670                 skip "willread ladvise is not supported"
22671
22672         ladvise_no_ioctl $DIR/$tfile &&
22673                 skip "ladvise ioctl is not supported"
22674
22675         local size_mb=100
22676         local size=$((size_mb * 1048576))
22677         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22678                 error "dd to $DIR/$tfile failed"
22679
22680         lfs ladvise -a willread $DIR/$tfile ||
22681                 error "Ladvise failed with no range argument"
22682
22683         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22684                 error "Ladvise failed with no -l or -e argument"
22685
22686         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22687                 error "Ladvise failed with only -e argument"
22688
22689         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22690                 error "Ladvise failed with only -l argument"
22691
22692         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22693                 error "End offset should not be smaller than start offset"
22694
22695         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22696                 error "End offset should not be equal to start offset"
22697
22698         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22699                 error "Ladvise failed with overflowing -s argument"
22700
22701         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22702                 error "Ladvise failed with overflowing -e argument"
22703
22704         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22705                 error "Ladvise failed with overflowing -l argument"
22706
22707         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22708                 error "Ladvise succeeded with conflicting -l and -e arguments"
22709
22710         echo "Synchronous ladvise should wait"
22711         local delay=4
22712 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22713         do_nodes $(comma_list $(osts_nodes)) \
22714                 $LCTL set_param fail_val=$delay fail_loc=0x237
22715
22716         local start_ts=$SECONDS
22717         lfs ladvise -a willread $DIR/$tfile ||
22718                 error "Ladvise failed with no range argument"
22719         local end_ts=$SECONDS
22720         local inteval_ts=$((end_ts - start_ts))
22721
22722         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22723                 error "Synchronous advice didn't wait reply"
22724         fi
22725
22726         echo "Asynchronous ladvise shouldn't wait"
22727         local start_ts=$SECONDS
22728         lfs ladvise -a willread -b $DIR/$tfile ||
22729                 error "Ladvise failed with no range argument"
22730         local end_ts=$SECONDS
22731         local inteval_ts=$((end_ts - start_ts))
22732
22733         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22734                 error "Asynchronous advice blocked"
22735         fi
22736
22737         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22738         ladvise_willread_performance
22739 }
22740 run_test 255a "check 'lfs ladvise -a willread'"
22741
22742 facet_meminfo() {
22743         local facet=$1
22744         local info=$2
22745
22746         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22747 }
22748
22749 test_255b() {
22750         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22751                 skip "lustre < 2.8.54 does not support ladvise "
22752         remote_ost_nodsh && skip "remote OST with nodsh"
22753
22754         stack_trap "rm -f $DIR/$tfile"
22755         lfs setstripe -c 1 -i 0 $DIR/$tfile
22756
22757         ladvise_no_type dontneed $DIR/$tfile &&
22758                 skip "dontneed ladvise is not supported"
22759
22760         ladvise_no_ioctl $DIR/$tfile &&
22761                 skip "ladvise ioctl is not supported"
22762
22763         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22764                 [ "$ost1_FSTYPE" = "zfs" ] &&
22765                 skip "zfs-osd does not support 'ladvise dontneed'"
22766
22767         local size_mb=100
22768         local size=$((size_mb * 1048576))
22769         # In order to prevent disturbance of other processes, only check 3/4
22770         # of the memory usage
22771         local kibibytes=$((size_mb * 1024 * 3 / 4))
22772
22773         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22774                 error "dd to $DIR/$tfile failed"
22775
22776         #force write to complete before dropping OST cache & checking memory
22777         sync
22778
22779         local total=$(facet_meminfo ost1 MemTotal)
22780         echo "Total memory: $total KiB"
22781
22782         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22783         local before_read=$(facet_meminfo ost1 Cached)
22784         echo "Cache used before read: $before_read KiB"
22785
22786         lfs ladvise -a willread $DIR/$tfile ||
22787                 error "Ladvise willread failed"
22788         local after_read=$(facet_meminfo ost1 Cached)
22789         echo "Cache used after read: $after_read KiB"
22790
22791         lfs ladvise -a dontneed $DIR/$tfile ||
22792                 error "Ladvise dontneed again failed"
22793         local no_read=$(facet_meminfo ost1 Cached)
22794         echo "Cache used after dontneed ladvise: $no_read KiB"
22795
22796         if [ $total -lt $((before_read + kibibytes)) ]; then
22797                 echo "Memory is too small, abort checking"
22798                 return 0
22799         fi
22800
22801         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22802                 error "Ladvise willread should use more memory" \
22803                         "than $kibibytes KiB"
22804         fi
22805
22806         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22807                 error "Ladvise dontneed should release more memory" \
22808                         "than $kibibytes KiB"
22809         fi
22810 }
22811 run_test 255b "check 'lfs ladvise -a dontneed'"
22812
22813 test_255c() {
22814         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22815                 skip "lustre < 2.10.50 does not support lockahead"
22816
22817         local ost1_imp=$(get_osc_import_name client ost1)
22818         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22819                          cut -d'.' -f2)
22820         local count
22821         local new_count
22822         local difference
22823         local i
22824         local rc
22825
22826         test_mkdir -p $DIR/$tdir
22827         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22828
22829         #test 10 returns only success/failure
22830         i=10
22831         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22832         rc=$?
22833         if [ $rc -eq 255 ]; then
22834                 error "Ladvise test${i} failed, ${rc}"
22835         fi
22836
22837         #test 11 counts lock enqueue requests, all others count new locks
22838         i=11
22839         count=$(do_facet ost1 \
22840                 $LCTL get_param -n ost.OSS.ost.stats)
22841         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22842
22843         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22844         rc=$?
22845         if [ $rc -eq 255 ]; then
22846                 error "Ladvise test${i} failed, ${rc}"
22847         fi
22848
22849         new_count=$(do_facet ost1 \
22850                 $LCTL get_param -n ost.OSS.ost.stats)
22851         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22852                    awk '{ print $2 }')
22853
22854         difference="$((new_count - count))"
22855         if [ $difference -ne $rc ]; then
22856                 error "Ladvise test${i}, bad enqueue count, returned " \
22857                       "${rc}, actual ${difference}"
22858         fi
22859
22860         for i in $(seq 12 21); do
22861                 # If we do not do this, we run the risk of having too many
22862                 # locks and starting lock cancellation while we are checking
22863                 # lock counts.
22864                 cancel_lru_locks osc
22865
22866                 count=$($LCTL get_param -n \
22867                        ldlm.namespaces.$imp_name.lock_unused_count)
22868
22869                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22870                 rc=$?
22871                 if [ $rc -eq 255 ]; then
22872                         error "Ladvise test ${i} failed, ${rc}"
22873                 fi
22874
22875                 new_count=$($LCTL get_param -n \
22876                        ldlm.namespaces.$imp_name.lock_unused_count)
22877                 difference="$((new_count - count))"
22878
22879                 # Test 15 output is divided by 100 to map down to valid return
22880                 if [ $i -eq 15 ]; then
22881                         rc="$((rc * 100))"
22882                 fi
22883
22884                 if [ $difference -ne $rc ]; then
22885                         error "Ladvise test ${i}, bad lock count, returned " \
22886                               "${rc}, actual ${difference}"
22887                 fi
22888         done
22889
22890         #test 22 returns only success/failure
22891         i=22
22892         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22893         rc=$?
22894         if [ $rc -eq 255 ]; then
22895                 error "Ladvise test${i} failed, ${rc}"
22896         fi
22897 }
22898 run_test 255c "suite of ladvise lockahead tests"
22899
22900 test_256() {
22901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22902         remote_mds_nodsh && skip "remote MDS with nodsh"
22903         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22904         changelog_users $SINGLEMDS | grep "^cl" &&
22905                 skip "active changelog user"
22906
22907         local cl_user
22908         local cat_sl
22909         local mdt_dev
22910
22911         mdt_dev=$(facet_device $SINGLEMDS)
22912         echo $mdt_dev
22913
22914         changelog_register || error "changelog_register failed"
22915
22916         rm -rf $DIR/$tdir
22917         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22918
22919         changelog_clear 0 || error "changelog_clear failed"
22920
22921         # change something
22922         touch $DIR/$tdir/{1..10}
22923
22924         # stop the MDT
22925         stop $SINGLEMDS || error "Fail to stop MDT"
22926
22927         # remount the MDT
22928         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22929                 error "Fail to start MDT"
22930
22931         #after mount new plainllog is used
22932         touch $DIR/$tdir/{11..19}
22933         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22934         stack_trap "rm -f $tmpfile"
22935         cat_sl=$(do_facet $SINGLEMDS "sync; \
22936                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22937                  llog_reader $tmpfile | grep -c type=1064553b")
22938         do_facet $SINGLEMDS llog_reader $tmpfile
22939
22940         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22941
22942         changelog_clear 0 || error "changelog_clear failed"
22943
22944         cat_sl=$(do_facet $SINGLEMDS "sync; \
22945                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22946                  llog_reader $tmpfile | grep -c type=1064553b")
22947
22948         if (( cat_sl == 2 )); then
22949                 error "Empty plain llog was not deleted from changelog catalog"
22950         elif (( cat_sl != 1 )); then
22951                 error "Active plain llog shouldn't be deleted from catalog"
22952         fi
22953 }
22954 run_test 256 "Check llog delete for empty and not full state"
22955
22956 test_257() {
22957         remote_mds_nodsh && skip "remote MDS with nodsh"
22958         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22959                 skip "Need MDS version at least 2.8.55"
22960
22961         test_mkdir $DIR/$tdir
22962
22963         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22964                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22965         stat $DIR/$tdir
22966
22967 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22968         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22969         local facet=mds$((mdtidx + 1))
22970         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22971         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22972
22973         stop $facet || error "stop MDS failed"
22974         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22975                 error "start MDS fail"
22976         wait_recovery_complete $facet
22977 }
22978 run_test 257 "xattr locks are not lost"
22979
22980 # Verify we take the i_mutex when security requires it
22981 test_258a() {
22982 #define OBD_FAIL_IMUTEX_SEC 0x141c
22983         $LCTL set_param fail_loc=0x141c
22984         touch $DIR/$tfile
22985         chmod u+s $DIR/$tfile
22986         chmod a+rwx $DIR/$tfile
22987         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22988         RC=$?
22989         if [ $RC -ne 0 ]; then
22990                 error "error, failed to take i_mutex, rc=$?"
22991         fi
22992         rm -f $DIR/$tfile
22993 }
22994 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22995
22996 # Verify we do NOT take the i_mutex in the normal case
22997 test_258b() {
22998 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22999         $LCTL set_param fail_loc=0x141d
23000         touch $DIR/$tfile
23001         chmod a+rwx $DIR
23002         chmod a+rw $DIR/$tfile
23003         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23004         RC=$?
23005         if [ $RC -ne 0 ]; then
23006                 error "error, took i_mutex unnecessarily, rc=$?"
23007         fi
23008         rm -f $DIR/$tfile
23009
23010 }
23011 run_test 258b "verify i_mutex security behavior"
23012
23013 test_259() {
23014         local file=$DIR/$tfile
23015         local before
23016         local after
23017
23018         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23019
23020         stack_trap "rm -f $file" EXIT
23021
23022         wait_delete_completed
23023         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23024         echo "before: $before"
23025
23026         $LFS setstripe -i 0 -c 1 $file
23027         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23028         sync_all_data
23029         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23030         echo "after write: $after"
23031
23032 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23033         do_facet ost1 $LCTL set_param fail_loc=0x2301
23034         $TRUNCATE $file 0
23035         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23036         echo "after truncate: $after"
23037
23038         stop ost1
23039         do_facet ost1 $LCTL set_param fail_loc=0
23040         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23041         sleep 2
23042         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23043         echo "after restart: $after"
23044         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23045                 error "missing truncate?"
23046
23047         return 0
23048 }
23049 run_test 259 "crash at delayed truncate"
23050
23051 test_260() {
23052 #define OBD_FAIL_MDC_CLOSE               0x806
23053         $LCTL set_param fail_loc=0x80000806
23054         touch $DIR/$tfile
23055
23056 }
23057 run_test 260 "Check mdc_close fail"
23058
23059 ### Data-on-MDT sanity tests ###
23060 test_270a() {
23061         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23062                 skip "Need MDS version at least 2.10.55 for DoM"
23063
23064         # create DoM file
23065         local dom=$DIR/$tdir/dom_file
23066         local tmp=$DIR/$tdir/tmp_file
23067
23068         mkdir_on_mdt0 $DIR/$tdir
23069
23070         # basic checks for DoM component creation
23071         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23072                 error "Can set MDT layout to non-first entry"
23073
23074         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23075                 error "Can define multiple entries as MDT layout"
23076
23077         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23078
23079         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23080         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23081         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23082
23083         local mdtidx=$($LFS getstripe -m $dom)
23084         local mdtname=MDT$(printf %04x $mdtidx)
23085         local facet=mds$((mdtidx + 1))
23086         local space_check=1
23087
23088         # Skip free space checks with ZFS
23089         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23090
23091         # write
23092         sync
23093         local size_tmp=$((65536 * 3))
23094         local mdtfree1=$(do_facet $facet \
23095                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23096
23097         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23098         # check also direct IO along write
23099         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23100         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23101         sync
23102         cmp $tmp $dom || error "file data is different"
23103         [ $(stat -c%s $dom) == $size_tmp ] ||
23104                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23105         if [ $space_check == 1 ]; then
23106                 local mdtfree2=$(do_facet $facet \
23107                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23108
23109                 # increase in usage from by $size_tmp
23110                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23111                         error "MDT free space wrong after write: " \
23112                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23113         fi
23114
23115         # truncate
23116         local size_dom=10000
23117
23118         $TRUNCATE $dom $size_dom
23119         [ $(stat -c%s $dom) == $size_dom ] ||
23120                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23121         if [ $space_check == 1 ]; then
23122                 mdtfree1=$(do_facet $facet \
23123                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23124                 # decrease in usage from $size_tmp to new $size_dom
23125                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23126                   $(((size_tmp - size_dom) / 1024)) ] ||
23127                         error "MDT free space is wrong after truncate: " \
23128                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23129         fi
23130
23131         # append
23132         cat $tmp >> $dom
23133         sync
23134         size_dom=$((size_dom + size_tmp))
23135         [ $(stat -c%s $dom) == $size_dom ] ||
23136                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23137         if [ $space_check == 1 ]; then
23138                 mdtfree2=$(do_facet $facet \
23139                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23140                 # increase in usage by $size_tmp from previous
23141                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23142                         error "MDT free space is wrong after append: " \
23143                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23144         fi
23145
23146         # delete
23147         rm $dom
23148         if [ $space_check == 1 ]; then
23149                 mdtfree1=$(do_facet $facet \
23150                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23151                 # decrease in usage by $size_dom from previous
23152                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23153                         error "MDT free space is wrong after removal: " \
23154                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23155         fi
23156
23157         # combined striping
23158         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23159                 error "Can't create DoM + OST striping"
23160
23161         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23162         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23163         # check also direct IO along write
23164         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23165         sync
23166         cmp $tmp $dom || error "file data is different"
23167         [ $(stat -c%s $dom) == $size_tmp ] ||
23168                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23169         rm $dom $tmp
23170
23171         return 0
23172 }
23173 run_test 270a "DoM: basic functionality tests"
23174
23175 test_270b() {
23176         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23177                 skip "Need MDS version at least 2.10.55"
23178
23179         local dom=$DIR/$tdir/dom_file
23180         local max_size=1048576
23181
23182         mkdir -p $DIR/$tdir
23183         $LFS setstripe -E $max_size -L mdt $dom
23184
23185         # truncate over the limit
23186         $TRUNCATE $dom $(($max_size + 1)) &&
23187                 error "successful truncate over the maximum size"
23188         # write over the limit
23189         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23190                 error "successful write over the maximum size"
23191         # append over the limit
23192         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23193         echo "12345" >> $dom && error "successful append over the maximum size"
23194         rm $dom
23195
23196         return 0
23197 }
23198 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23199
23200 test_270c() {
23201         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23202                 skip "Need MDS version at least 2.10.55"
23203
23204         mkdir -p $DIR/$tdir
23205         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23206
23207         # check files inherit DoM EA
23208         touch $DIR/$tdir/first
23209         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23210                 error "bad pattern"
23211         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23212                 error "bad stripe count"
23213         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23214                 error "bad stripe size"
23215
23216         # check directory inherits DoM EA and uses it as default
23217         mkdir $DIR/$tdir/subdir
23218         touch $DIR/$tdir/subdir/second
23219         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23220                 error "bad pattern in sub-directory"
23221         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23222                 error "bad stripe count in sub-directory"
23223         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23224                 error "bad stripe size in sub-directory"
23225         return 0
23226 }
23227 run_test 270c "DoM: DoM EA inheritance tests"
23228
23229 test_270d() {
23230         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23231                 skip "Need MDS version at least 2.10.55"
23232
23233         mkdir -p $DIR/$tdir
23234         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23235
23236         # inherit default DoM striping
23237         mkdir $DIR/$tdir/subdir
23238         touch $DIR/$tdir/subdir/f1
23239
23240         # change default directory striping
23241         $LFS setstripe -c 1 $DIR/$tdir/subdir
23242         touch $DIR/$tdir/subdir/f2
23243         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23244                 error "wrong default striping in file 2"
23245         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23246                 error "bad pattern in file 2"
23247         return 0
23248 }
23249 run_test 270d "DoM: change striping from DoM to RAID0"
23250
23251 test_270e() {
23252         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23253                 skip "Need MDS version at least 2.10.55"
23254
23255         mkdir -p $DIR/$tdir/dom
23256         mkdir -p $DIR/$tdir/norm
23257         DOMFILES=20
23258         NORMFILES=10
23259         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23260         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23261
23262         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23263         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23264
23265         # find DoM files by layout
23266         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23267         [ $NUM -eq  $DOMFILES ] ||
23268                 error "lfs find -L: found $NUM, expected $DOMFILES"
23269         echo "Test 1: lfs find 20 DOM files by layout: OK"
23270
23271         # there should be 1 dir with default DOM striping
23272         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23273         [ $NUM -eq  1 ] ||
23274                 error "lfs find -L: found $NUM, expected 1 dir"
23275         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23276
23277         # find DoM files by stripe size
23278         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23279         [ $NUM -eq  $DOMFILES ] ||
23280                 error "lfs find -S: found $NUM, expected $DOMFILES"
23281         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23282
23283         # find files by stripe offset except DoM files
23284         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23285         [ $NUM -eq  $NORMFILES ] ||
23286                 error "lfs find -i: found $NUM, expected $NORMFILES"
23287         echo "Test 5: lfs find no DOM files by stripe index: OK"
23288         return 0
23289 }
23290 run_test 270e "DoM: lfs find with DoM files test"
23291
23292 test_270f() {
23293         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23294                 skip "Need MDS version at least 2.10.55"
23295
23296         local mdtname=${FSNAME}-MDT0000-mdtlov
23297         local dom=$DIR/$tdir/dom_file
23298         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23299                                                 lod.$mdtname.dom_stripesize)
23300         local dom_limit=131072
23301
23302         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23303         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23304                                                 lod.$mdtname.dom_stripesize)
23305         [ ${dom_limit} -eq ${dom_current} ] ||
23306                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23307
23308         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23309         $LFS setstripe -d $DIR/$tdir
23310         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23311                 error "Can't set directory default striping"
23312
23313         # exceed maximum stripe size
23314         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23315                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23316         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23317                 error "Able to create DoM component size more than LOD limit"
23318
23319         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23320         dom_current=$(do_facet mds1 $LCTL get_param -n \
23321                                                 lod.$mdtname.dom_stripesize)
23322         [ 0 -eq ${dom_current} ] ||
23323                 error "Can't set zero DoM stripe limit"
23324         rm $dom
23325
23326         # attempt to create DoM file on server with disabled DoM should
23327         # remove DoM entry from layout and be succeed
23328         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23329                 error "Can't create DoM file (DoM is disabled)"
23330         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23331                 error "File has DoM component while DoM is disabled"
23332         rm $dom
23333
23334         # attempt to create DoM file with only DoM stripe should return error
23335         $LFS setstripe -E $dom_limit -L mdt $dom &&
23336                 error "Able to create DoM-only file while DoM is disabled"
23337
23338         # too low values to be aligned with smallest stripe size 64K
23339         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23340         dom_current=$(do_facet mds1 $LCTL get_param -n \
23341                                                 lod.$mdtname.dom_stripesize)
23342         [ 30000 -eq ${dom_current} ] &&
23343                 error "Can set too small DoM stripe limit"
23344
23345         # 64K is a minimal stripe size in Lustre, expect limit of that size
23346         [ 65536 -eq ${dom_current} ] ||
23347                 error "Limit is not set to 64K but ${dom_current}"
23348
23349         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23350         dom_current=$(do_facet mds1 $LCTL get_param -n \
23351                                                 lod.$mdtname.dom_stripesize)
23352         echo $dom_current
23353         [ 2147483648 -eq ${dom_current} ] &&
23354                 error "Can set too large DoM stripe limit"
23355
23356         do_facet mds1 $LCTL set_param -n \
23357                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23358         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23359                 error "Can't create DoM component size after limit change"
23360         do_facet mds1 $LCTL set_param -n \
23361                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23362         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23363                 error "Can't create DoM file after limit decrease"
23364         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23365                 error "Can create big DoM component after limit decrease"
23366         touch ${dom}_def ||
23367                 error "Can't create file with old default layout"
23368
23369         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23370         return 0
23371 }
23372 run_test 270f "DoM: maximum DoM stripe size checks"
23373
23374 test_270g() {
23375         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23376                 skip "Need MDS version at least 2.13.52"
23377         local dom=$DIR/$tdir/$tfile
23378
23379         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23380         local lodname=${FSNAME}-MDT0000-mdtlov
23381
23382         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23383         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23384         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23385         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23386
23387         local dom_limit=1024
23388         local dom_threshold="50%"
23389
23390         $LFS setstripe -d $DIR/$tdir
23391         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23392                 error "Can't set directory default striping"
23393
23394         do_facet mds1 $LCTL set_param -n \
23395                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23396         # set 0 threshold and create DOM file to change tunable stripesize
23397         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23398         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23399                 error "Failed to create $dom file"
23400         # now tunable dom_cur_stripesize should reach maximum
23401         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23402                                         lod.${lodname}.dom_stripesize_cur_kb)
23403         [[ $dom_current == $dom_limit ]] ||
23404                 error "Current DOM stripesize is not maximum"
23405         rm $dom
23406
23407         # set threshold for further tests
23408         do_facet mds1 $LCTL set_param -n \
23409                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23410         echo "DOM threshold is $dom_threshold free space"
23411         local dom_def
23412         local dom_set
23413         # Spoof bfree to exceed threshold
23414         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23415         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23416         for spfree in 40 20 0 15 30 55; do
23417                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23418                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23419                         error "Failed to create $dom file"
23420                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23421                                         lod.${lodname}.dom_stripesize_cur_kb)
23422                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23423                 [[ $dom_def != $dom_current ]] ||
23424                         error "Default stripe size was not changed"
23425                 if (( spfree > 0 )) ; then
23426                         dom_set=$($LFS getstripe -S $dom)
23427                         (( dom_set == dom_def * 1024 )) ||
23428                                 error "DOM component size is still old"
23429                 else
23430                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23431                                 error "DoM component is set with no free space"
23432                 fi
23433                 rm $dom
23434                 dom_current=$dom_def
23435         done
23436 }
23437 run_test 270g "DoM: default DoM stripe size depends on free space"
23438
23439 test_270h() {
23440         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23441                 skip "Need MDS version at least 2.13.53"
23442
23443         local mdtname=${FSNAME}-MDT0000-mdtlov
23444         local dom=$DIR/$tdir/$tfile
23445         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23446
23447         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23448         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23449
23450         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23451         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23452                 error "can't create OST file"
23453         # mirrored file with DOM entry in the second mirror
23454         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23455                 error "can't create mirror with DoM component"
23456
23457         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23458
23459         # DOM component in the middle and has other enries in the same mirror,
23460         # should succeed but lost DoM component
23461         $LFS setstripe --copy=${dom}_1 $dom ||
23462                 error "Can't create file from OST|DOM mirror layout"
23463         # check new file has no DoM layout after all
23464         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23465                 error "File has DoM component while DoM is disabled"
23466 }
23467 run_test 270h "DoM: DoM stripe removal when disabled on server"
23468
23469 test_270i() {
23470         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23471                 skip "Need MDS version at least 2.14.54"
23472
23473         mkdir $DIR/$tdir
23474         # DoM with plain layout
23475         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23476                 error "default plain layout with DoM must fail"
23477         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23478                 error "setstripe plain file layout with DoM must fail"
23479         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23480                 error "default DoM layout with bad striping must fail"
23481         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23482                 error "setstripe to DoM layout with bad striping must fail"
23483         return 0
23484 }
23485 run_test 270i "DoM: setting invalid DoM striping should fail"
23486
23487 test_271a() {
23488         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23489                 skip "Need MDS version at least 2.10.55"
23490
23491         local dom=$DIR/$tdir/dom
23492
23493         mkdir -p $DIR/$tdir
23494
23495         $LFS setstripe -E 1024K -L mdt $dom
23496
23497         lctl set_param -n mdc.*.stats=clear
23498         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23499         cat $dom > /dev/null
23500         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23501         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23502         ls $dom
23503         rm -f $dom
23504 }
23505 run_test 271a "DoM: data is cached for read after write"
23506
23507 test_271b() {
23508         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23509                 skip "Need MDS version at least 2.10.55"
23510
23511         local dom=$DIR/$tdir/dom
23512
23513         mkdir -p $DIR/$tdir
23514
23515         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23516
23517         lctl set_param -n mdc.*.stats=clear
23518         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23519         cancel_lru_locks mdc
23520         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23521         # second stat to check size is cached on client
23522         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23523         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23524         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23525         rm -f $dom
23526 }
23527 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23528
23529 test_271ba() {
23530         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23531                 skip "Need MDS version at least 2.10.55"
23532
23533         local dom=$DIR/$tdir/dom
23534
23535         mkdir -p $DIR/$tdir
23536
23537         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23538
23539         lctl set_param -n mdc.*.stats=clear
23540         lctl set_param -n osc.*.stats=clear
23541         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23542         cancel_lru_locks mdc
23543         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23544         # second stat to check size is cached on client
23545         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23546         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23547         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23548         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23549         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23550         rm -f $dom
23551 }
23552 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23553
23554
23555 get_mdc_stats() {
23556         local mdtidx=$1
23557         local param=$2
23558         local mdt=MDT$(printf %04x $mdtidx)
23559
23560         if [ -z $param ]; then
23561                 lctl get_param -n mdc.*$mdt*.stats
23562         else
23563                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23564         fi
23565 }
23566
23567 test_271c() {
23568         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23569                 skip "Need MDS version at least 2.10.55"
23570
23571         local dom=$DIR/$tdir/dom
23572
23573         mkdir -p $DIR/$tdir
23574
23575         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23576
23577         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23578         local facet=mds$((mdtidx + 1))
23579
23580         cancel_lru_locks mdc
23581         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23582         createmany -o $dom 1000
23583         lctl set_param -n mdc.*.stats=clear
23584         smalliomany -w $dom 1000 200
23585         get_mdc_stats $mdtidx
23586         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23587         # Each file has 1 open, 1 IO enqueues, total 2000
23588         # but now we have also +1 getxattr for security.capability, total 3000
23589         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23590         unlinkmany $dom 1000
23591
23592         cancel_lru_locks mdc
23593         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23594         createmany -o $dom 1000
23595         lctl set_param -n mdc.*.stats=clear
23596         smalliomany -w $dom 1000 200
23597         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23598         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23599         # for OPEN and IO lock.
23600         [ $((enq - enq_2)) -ge 1000 ] ||
23601                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23602         unlinkmany $dom 1000
23603         return 0
23604 }
23605 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23606
23607 cleanup_271def_tests() {
23608         trap 0
23609         rm -f $1
23610 }
23611
23612 test_271d() {
23613         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23614                 skip "Need MDS version at least 2.10.57"
23615
23616         local dom=$DIR/$tdir/dom
23617         local tmp=$TMP/$tfile
23618         trap "cleanup_271def_tests $tmp" EXIT
23619
23620         mkdir -p $DIR/$tdir
23621
23622         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23623
23624         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23625
23626         cancel_lru_locks mdc
23627         dd if=/dev/urandom of=$tmp bs=1000 count=1
23628         dd if=$tmp of=$dom bs=1000 count=1
23629         cancel_lru_locks mdc
23630
23631         cat /etc/hosts >> $tmp
23632         lctl set_param -n mdc.*.stats=clear
23633
23634         # append data to the same file it should update local page
23635         echo "Append to the same page"
23636         cat /etc/hosts >> $dom
23637         local num=$(get_mdc_stats $mdtidx ost_read)
23638         local ra=$(get_mdc_stats $mdtidx req_active)
23639         local rw=$(get_mdc_stats $mdtidx req_waittime)
23640
23641         [ -z $num ] || error "$num READ RPC occured"
23642         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23643         echo "... DONE"
23644
23645         # compare content
23646         cmp $tmp $dom || error "file miscompare"
23647
23648         cancel_lru_locks mdc
23649         lctl set_param -n mdc.*.stats=clear
23650
23651         echo "Open and read file"
23652         cat $dom > /dev/null
23653         local num=$(get_mdc_stats $mdtidx ost_read)
23654         local ra=$(get_mdc_stats $mdtidx req_active)
23655         local rw=$(get_mdc_stats $mdtidx req_waittime)
23656
23657         [ -z $num ] || error "$num READ RPC occured"
23658         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23659         echo "... DONE"
23660
23661         # compare content
23662         cmp $tmp $dom || error "file miscompare"
23663
23664         return 0
23665 }
23666 run_test 271d "DoM: read on open (1K file in reply buffer)"
23667
23668 test_271f() {
23669         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23670                 skip "Need MDS version at least 2.10.57"
23671
23672         local dom=$DIR/$tdir/dom
23673         local tmp=$TMP/$tfile
23674         trap "cleanup_271def_tests $tmp" EXIT
23675
23676         mkdir -p $DIR/$tdir
23677
23678         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23679
23680         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23681
23682         cancel_lru_locks mdc
23683         dd if=/dev/urandom of=$tmp bs=265000 count=1
23684         dd if=$tmp of=$dom bs=265000 count=1
23685         cancel_lru_locks mdc
23686         cat /etc/hosts >> $tmp
23687         lctl set_param -n mdc.*.stats=clear
23688
23689         echo "Append to the same page"
23690         cat /etc/hosts >> $dom
23691         local num=$(get_mdc_stats $mdtidx ost_read)
23692         local ra=$(get_mdc_stats $mdtidx req_active)
23693         local rw=$(get_mdc_stats $mdtidx req_waittime)
23694
23695         [ -z $num ] || error "$num READ RPC occured"
23696         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23697         echo "... DONE"
23698
23699         # compare content
23700         cmp $tmp $dom || error "file miscompare"
23701
23702         cancel_lru_locks mdc
23703         lctl set_param -n mdc.*.stats=clear
23704
23705         echo "Open and read file"
23706         cat $dom > /dev/null
23707         local num=$(get_mdc_stats $mdtidx ost_read)
23708         local ra=$(get_mdc_stats $mdtidx req_active)
23709         local rw=$(get_mdc_stats $mdtidx req_waittime)
23710
23711         [ -z $num ] && num=0
23712         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23713         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23714         echo "... DONE"
23715
23716         # compare content
23717         cmp $tmp $dom || error "file miscompare"
23718
23719         return 0
23720 }
23721 run_test 271f "DoM: read on open (200K file and read tail)"
23722
23723 test_271g() {
23724         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23725                 skip "Skipping due to old client or server version"
23726
23727         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23728         # to get layout
23729         $CHECKSTAT -t file $DIR1/$tfile
23730
23731         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23732         MULTIOP_PID=$!
23733         sleep 1
23734         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23735         $LCTL set_param fail_loc=0x80000314
23736         rm $DIR1/$tfile || error "Unlink fails"
23737         RC=$?
23738         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23739         [ $RC -eq 0 ] || error "Failed write to stale object"
23740 }
23741 run_test 271g "Discard DoM data vs client flush race"
23742
23743 test_272a() {
23744         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23745                 skip "Need MDS version at least 2.11.50"
23746
23747         local dom=$DIR/$tdir/dom
23748         mkdir -p $DIR/$tdir
23749
23750         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23751         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23752                 error "failed to write data into $dom"
23753         local old_md5=$(md5sum $dom)
23754
23755         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23756                 error "failed to migrate to the same DoM component"
23757
23758         local new_md5=$(md5sum $dom)
23759
23760         [ "$old_md5" == "$new_md5" ] ||
23761                 error "md5sum differ: $old_md5, $new_md5"
23762
23763         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23764                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23765 }
23766 run_test 272a "DoM migration: new layout with the same DOM component"
23767
23768 test_272b() {
23769         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23770                 skip "Need MDS version at least 2.11.50"
23771
23772         local dom=$DIR/$tdir/dom
23773         mkdir -p $DIR/$tdir
23774         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23775
23776         local mdtidx=$($LFS getstripe -m $dom)
23777         local mdtname=MDT$(printf %04x $mdtidx)
23778         local facet=mds$((mdtidx + 1))
23779
23780         local mdtfree1=$(do_facet $facet \
23781                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23782         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23783                 error "failed to write data into $dom"
23784         local old_md5=$(md5sum $dom)
23785         cancel_lru_locks mdc
23786         local mdtfree1=$(do_facet $facet \
23787                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23788
23789         $LFS migrate -c2 $dom ||
23790                 error "failed to migrate to the new composite layout"
23791         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23792                 error "MDT stripe was not removed"
23793
23794         cancel_lru_locks mdc
23795         local new_md5=$(md5sum $dom)
23796         [ "$old_md5" == "$new_md5" ] ||
23797                 error "$old_md5 != $new_md5"
23798
23799         # Skip free space checks with ZFS
23800         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23801                 local mdtfree2=$(do_facet $facet \
23802                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23803                 [ $mdtfree2 -gt $mdtfree1 ] ||
23804                         error "MDT space is not freed after migration"
23805         fi
23806         return 0
23807 }
23808 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23809
23810 test_272c() {
23811         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23812                 skip "Need MDS version at least 2.11.50"
23813
23814         local dom=$DIR/$tdir/$tfile
23815         mkdir -p $DIR/$tdir
23816         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23817
23818         local mdtidx=$($LFS getstripe -m $dom)
23819         local mdtname=MDT$(printf %04x $mdtidx)
23820         local facet=mds$((mdtidx + 1))
23821
23822         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23823                 error "failed to write data into $dom"
23824         local old_md5=$(md5sum $dom)
23825         cancel_lru_locks mdc
23826         local mdtfree1=$(do_facet $facet \
23827                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23828
23829         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23830                 error "failed to migrate to the new composite layout"
23831         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23832                 error "MDT stripe was not removed"
23833
23834         cancel_lru_locks mdc
23835         local new_md5=$(md5sum $dom)
23836         [ "$old_md5" == "$new_md5" ] ||
23837                 error "$old_md5 != $new_md5"
23838
23839         # Skip free space checks with ZFS
23840         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23841                 local mdtfree2=$(do_facet $facet \
23842                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23843                 [ $mdtfree2 -gt $mdtfree1 ] ||
23844                         error "MDS space is not freed after migration"
23845         fi
23846         return 0
23847 }
23848 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23849
23850 test_272d() {
23851         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23852                 skip "Need MDS version at least 2.12.55"
23853
23854         local dom=$DIR/$tdir/$tfile
23855         mkdir -p $DIR/$tdir
23856         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23857
23858         local mdtidx=$($LFS getstripe -m $dom)
23859         local mdtname=MDT$(printf %04x $mdtidx)
23860         local facet=mds$((mdtidx + 1))
23861
23862         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23863                 error "failed to write data into $dom"
23864         local old_md5=$(md5sum $dom)
23865         cancel_lru_locks mdc
23866         local mdtfree1=$(do_facet $facet \
23867                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23868
23869         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23870                 error "failed mirroring to the new composite layout"
23871         $LFS mirror resync $dom ||
23872                 error "failed mirror resync"
23873         $LFS mirror split --mirror-id 1 -d $dom ||
23874                 error "failed mirror split"
23875
23876         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23877                 error "MDT stripe was not removed"
23878
23879         cancel_lru_locks mdc
23880         local new_md5=$(md5sum $dom)
23881         [ "$old_md5" == "$new_md5" ] ||
23882                 error "$old_md5 != $new_md5"
23883
23884         # Skip free space checks with ZFS
23885         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23886                 local mdtfree2=$(do_facet $facet \
23887                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23888                 [ $mdtfree2 -gt $mdtfree1 ] ||
23889                         error "MDS space is not freed after DOM mirror deletion"
23890         fi
23891         return 0
23892 }
23893 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23894
23895 test_272e() {
23896         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23897                 skip "Need MDS version at least 2.12.55"
23898
23899         local dom=$DIR/$tdir/$tfile
23900         mkdir -p $DIR/$tdir
23901         $LFS setstripe -c 2 $dom
23902
23903         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23904                 error "failed to write data into $dom"
23905         local old_md5=$(md5sum $dom)
23906         cancel_lru_locks
23907
23908         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23909                 error "failed mirroring to the DOM layout"
23910         $LFS mirror resync $dom ||
23911                 error "failed mirror resync"
23912         $LFS mirror split --mirror-id 1 -d $dom ||
23913                 error "failed mirror split"
23914
23915         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23916                 error "MDT stripe wasn't set"
23917
23918         cancel_lru_locks
23919         local new_md5=$(md5sum $dom)
23920         [ "$old_md5" == "$new_md5" ] ||
23921                 error "$old_md5 != $new_md5"
23922
23923         return 0
23924 }
23925 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23926
23927 test_272f() {
23928         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23929                 skip "Need MDS version at least 2.12.55"
23930
23931         local dom=$DIR/$tdir/$tfile
23932         mkdir -p $DIR/$tdir
23933         $LFS setstripe -c 2 $dom
23934
23935         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23936                 error "failed to write data into $dom"
23937         local old_md5=$(md5sum $dom)
23938         cancel_lru_locks
23939
23940         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23941                 error "failed migrating to the DOM file"
23942
23943         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23944                 error "MDT stripe wasn't set"
23945
23946         cancel_lru_locks
23947         local new_md5=$(md5sum $dom)
23948         [ "$old_md5" != "$new_md5" ] &&
23949                 error "$old_md5 != $new_md5"
23950
23951         return 0
23952 }
23953 run_test 272f "DoM migration: OST-striped file to DOM file"
23954
23955 test_273a() {
23956         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23957                 skip "Need MDS version at least 2.11.50"
23958
23959         # Layout swap cannot be done if either file has DOM component,
23960         # this will never be supported, migration should be used instead
23961
23962         local dom=$DIR/$tdir/$tfile
23963         mkdir -p $DIR/$tdir
23964
23965         $LFS setstripe -c2 ${dom}_plain
23966         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23967         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23968                 error "can swap layout with DoM component"
23969         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23970                 error "can swap layout with DoM component"
23971
23972         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23973         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23974                 error "can swap layout with DoM component"
23975         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23976                 error "can swap layout with DoM component"
23977         return 0
23978 }
23979 run_test 273a "DoM: layout swapping should fail with DOM"
23980
23981 test_273b() {
23982         mkdir -p $DIR/$tdir
23983         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23984
23985 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23986         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23987
23988         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23989 }
23990 run_test 273b "DoM: race writeback and object destroy"
23991
23992 test_273c() {
23993         mkdir -p $DIR/$tdir
23994         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
23995
23996         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
23997         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
23998
23999         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24000 }
24001 run_test 273c "race writeback and object destroy"
24002
24003 test_275() {
24004         remote_ost_nodsh && skip "remote OST with nodsh"
24005         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24006                 skip "Need OST version >= 2.10.57"
24007
24008         local file=$DIR/$tfile
24009         local oss
24010
24011         oss=$(comma_list $(osts_nodes))
24012
24013         dd if=/dev/urandom of=$file bs=1M count=2 ||
24014                 error "failed to create a file"
24015         cancel_lru_locks osc
24016
24017         #lock 1
24018         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24019                 error "failed to read a file"
24020
24021 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24022         $LCTL set_param fail_loc=0x8000031f
24023
24024         cancel_lru_locks osc &
24025         sleep 1
24026
24027 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24028         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24029         #IO takes another lock, but matches the PENDING one
24030         #and places it to the IO RPC
24031         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24032                 error "failed to read a file with PENDING lock"
24033 }
24034 run_test 275 "Read on a canceled duplicate lock"
24035
24036 test_276() {
24037         remote_ost_nodsh && skip "remote OST with nodsh"
24038         local pid
24039
24040         do_facet ost1 "(while true; do \
24041                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24042                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24043         pid=$!
24044
24045         for LOOP in $(seq 20); do
24046                 stop ost1
24047                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24048         done
24049         kill -9 $pid
24050         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24051                 rm $TMP/sanity_276_pid"
24052 }
24053 run_test 276 "Race between mount and obd_statfs"
24054
24055 test_277() {
24056         $LCTL set_param ldlm.namespaces.*.lru_size=0
24057         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24058         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24059                         grep ^used_mb | awk '{print $2}')
24060         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24062                 oflag=direct conv=notrunc
24063         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24064                         grep ^used_mb | awk '{print $2}')
24065         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24066 }
24067 run_test 277 "Direct IO shall drop page cache"
24068
24069 test_278() {
24070         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24071         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24072         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24073                 skip "needs the same host for mdt1 mdt2" && return
24074
24075         local pid1
24076         local pid2
24077
24078 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24079         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24080         stop mds2 &
24081         pid2=$!
24082
24083         stop mds1
24084
24085         echo "Starting MDTs"
24086         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24087         wait $pid2
24088 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24089 #will return NULL
24090         do_facet mds2 $LCTL set_param fail_loc=0
24091
24092         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24093         wait_recovery_complete mds2
24094 }
24095 run_test 278 "Race starting MDS between MDTs stop/start"
24096
24097 test_280() {
24098         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24099                 skip "Need MGS version at least 2.13.52"
24100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24101         combined_mgs_mds || skip "needs combined MGS/MDT"
24102
24103         umount_client $MOUNT
24104 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24105         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24106
24107         mount_client $MOUNT &
24108         sleep 1
24109         stop mgs || error "stop mgs failed"
24110         #for a race mgs would crash
24111         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24112         # make sure we unmount client before remounting
24113         wait
24114         umount_client $MOUNT
24115         mount_client $MOUNT || error "mount client failed"
24116 }
24117 run_test 280 "Race between MGS umount and client llog processing"
24118
24119 cleanup_test_300() {
24120         trap 0
24121         umask $SAVE_UMASK
24122 }
24123 test_striped_dir() {
24124         local mdt_index=$1
24125         local stripe_count
24126         local stripe_index
24127
24128         mkdir -p $DIR/$tdir
24129
24130         SAVE_UMASK=$(umask)
24131         trap cleanup_test_300 RETURN EXIT
24132
24133         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24134                                                 $DIR/$tdir/striped_dir ||
24135                 error "set striped dir error"
24136
24137         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24138         [ "$mode" = "755" ] || error "expect 755 got $mode"
24139
24140         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24141                 error "getdirstripe failed"
24142         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24143         if [ "$stripe_count" != "2" ]; then
24144                 error "1:stripe_count is $stripe_count, expect 2"
24145         fi
24146         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24147         if [ "$stripe_count" != "2" ]; then
24148                 error "2:stripe_count is $stripe_count, expect 2"
24149         fi
24150
24151         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24152         if [ "$stripe_index" != "$mdt_index" ]; then
24153                 error "stripe_index is $stripe_index, expect $mdt_index"
24154         fi
24155
24156         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24157                 error "nlink error after create striped dir"
24158
24159         mkdir $DIR/$tdir/striped_dir/a
24160         mkdir $DIR/$tdir/striped_dir/b
24161
24162         stat $DIR/$tdir/striped_dir/a ||
24163                 error "create dir under striped dir failed"
24164         stat $DIR/$tdir/striped_dir/b ||
24165                 error "create dir under striped dir failed"
24166
24167         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24168                 error "nlink error after mkdir"
24169
24170         rmdir $DIR/$tdir/striped_dir/a
24171         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24172                 error "nlink error after rmdir"
24173
24174         rmdir $DIR/$tdir/striped_dir/b
24175         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24176                 error "nlink error after rmdir"
24177
24178         chattr +i $DIR/$tdir/striped_dir
24179         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24180                 error "immutable flags not working under striped dir!"
24181         chattr -i $DIR/$tdir/striped_dir
24182
24183         rmdir $DIR/$tdir/striped_dir ||
24184                 error "rmdir striped dir error"
24185
24186         cleanup_test_300
24187
24188         true
24189 }
24190
24191 test_300a() {
24192         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24193                 skip "skipped for lustre < 2.7.0"
24194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24196
24197         test_striped_dir 0 || error "failed on striped dir on MDT0"
24198         test_striped_dir 1 || error "failed on striped dir on MDT0"
24199 }
24200 run_test 300a "basic striped dir sanity test"
24201
24202 test_300b() {
24203         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24204                 skip "skipped for lustre < 2.7.0"
24205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24207
24208         local i
24209         local mtime1
24210         local mtime2
24211         local mtime3
24212
24213         test_mkdir $DIR/$tdir || error "mkdir fail"
24214         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24215                 error "set striped dir error"
24216         for i in {0..9}; do
24217                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24218                 sleep 1
24219                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24220                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24221                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24222                 sleep 1
24223                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24224                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24225                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24226         done
24227         true
24228 }
24229 run_test 300b "check ctime/mtime for striped dir"
24230
24231 test_300c() {
24232         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24233                 skip "skipped for lustre < 2.7.0"
24234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24236
24237         local file_count
24238
24239         mkdir_on_mdt0 $DIR/$tdir
24240         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24241                 error "set striped dir error"
24242
24243         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24244                 error "chown striped dir failed"
24245
24246         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24247                 error "create 5k files failed"
24248
24249         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24250
24251         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24252
24253         rm -rf $DIR/$tdir
24254 }
24255 run_test 300c "chown && check ls under striped directory"
24256
24257 test_300d() {
24258         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24259                 skip "skipped for lustre < 2.7.0"
24260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24262
24263         local stripe_count
24264         local file
24265
24266         mkdir -p $DIR/$tdir
24267         $LFS setstripe -c 2 $DIR/$tdir
24268
24269         #local striped directory
24270         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24271                 error "set striped dir error"
24272         #look at the directories for debug purposes
24273         ls -l $DIR/$tdir
24274         $LFS getdirstripe $DIR/$tdir
24275         ls -l $DIR/$tdir/striped_dir
24276         $LFS getdirstripe $DIR/$tdir/striped_dir
24277         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24278                 error "create 10 files failed"
24279
24280         #remote striped directory
24281         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24282                 error "set striped dir error"
24283         #look at the directories for debug purposes
24284         ls -l $DIR/$tdir
24285         $LFS getdirstripe $DIR/$tdir
24286         ls -l $DIR/$tdir/remote_striped_dir
24287         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24288         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24289                 error "create 10 files failed"
24290
24291         for file in $(find $DIR/$tdir); do
24292                 stripe_count=$($LFS getstripe -c $file)
24293                 [ $stripe_count -eq 2 ] ||
24294                         error "wrong stripe $stripe_count for $file"
24295         done
24296
24297         rm -rf $DIR/$tdir
24298 }
24299 run_test 300d "check default stripe under striped directory"
24300
24301 test_300e() {
24302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24303                 skip "Need MDS version at least 2.7.55"
24304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24306
24307         local stripe_count
24308         local file
24309
24310         mkdir -p $DIR/$tdir
24311
24312         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24313                 error "set striped dir error"
24314
24315         touch $DIR/$tdir/striped_dir/a
24316         touch $DIR/$tdir/striped_dir/b
24317         touch $DIR/$tdir/striped_dir/c
24318
24319         mkdir $DIR/$tdir/striped_dir/dir_a
24320         mkdir $DIR/$tdir/striped_dir/dir_b
24321         mkdir $DIR/$tdir/striped_dir/dir_c
24322
24323         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24324                 error "set striped adir under striped dir error"
24325
24326         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24327                 error "set striped bdir under striped dir error"
24328
24329         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24330                 error "set striped cdir under striped dir error"
24331
24332         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24333                 error "rename dir under striped dir fails"
24334
24335         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24336                 error "rename dir under different stripes fails"
24337
24338         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24339                 error "rename file under striped dir should succeed"
24340
24341         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24342                 error "rename dir under striped dir should succeed"
24343
24344         rm -rf $DIR/$tdir
24345 }
24346 run_test 300e "check rename under striped directory"
24347
24348 test_300f() {
24349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24351         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24352                 skip "Need MDS version at least 2.7.55"
24353
24354         local stripe_count
24355         local file
24356
24357         rm -rf $DIR/$tdir
24358         mkdir -p $DIR/$tdir
24359
24360         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24361                 error "set striped dir error"
24362
24363         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24364                 error "set striped dir error"
24365
24366         touch $DIR/$tdir/striped_dir/a
24367         mkdir $DIR/$tdir/striped_dir/dir_a
24368         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24369                 error "create striped dir under striped dir fails"
24370
24371         touch $DIR/$tdir/striped_dir1/b
24372         mkdir $DIR/$tdir/striped_dir1/dir_b
24373         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24374                 error "create striped dir under striped dir fails"
24375
24376         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24377                 error "rename dir under different striped dir should fail"
24378
24379         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24380                 error "rename striped dir under diff striped dir should fail"
24381
24382         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24383                 error "rename file under diff striped dirs fails"
24384
24385         rm -rf $DIR/$tdir
24386 }
24387 run_test 300f "check rename cross striped directory"
24388
24389 test_300_check_default_striped_dir()
24390 {
24391         local dirname=$1
24392         local default_count=$2
24393         local default_index=$3
24394         local stripe_count
24395         local stripe_index
24396         local dir_stripe_index
24397         local dir
24398
24399         echo "checking $dirname $default_count $default_index"
24400         $LFS setdirstripe -D -c $default_count -i $default_index \
24401                                 -H all_char $DIR/$tdir/$dirname ||
24402                 error "set default stripe on striped dir error"
24403         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24404         [ $stripe_count -eq $default_count ] ||
24405                 error "expect $default_count get $stripe_count for $dirname"
24406
24407         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24408         [ $stripe_index -eq $default_index ] ||
24409                 error "expect $default_index get $stripe_index for $dirname"
24410
24411         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24412                                                 error "create dirs failed"
24413
24414         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24415         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24416         for dir in $(find $DIR/$tdir/$dirname/*); do
24417                 stripe_count=$($LFS getdirstripe -c $dir)
24418                 (( $stripe_count == $default_count )) ||
24419                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24420                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24421                 error "stripe count $default_count != $stripe_count for $dir"
24422
24423                 stripe_index=$($LFS getdirstripe -i $dir)
24424                 [ $default_index -eq -1 ] ||
24425                         [ $stripe_index -eq $default_index ] ||
24426                         error "$stripe_index != $default_index for $dir"
24427
24428                 #check default stripe
24429                 stripe_count=$($LFS getdirstripe -D -c $dir)
24430                 [ $stripe_count -eq $default_count ] ||
24431                 error "default count $default_count != $stripe_count for $dir"
24432
24433                 stripe_index=$($LFS getdirstripe -D -i $dir)
24434                 [ $stripe_index -eq $default_index ] ||
24435                 error "default index $default_index != $stripe_index for $dir"
24436         done
24437         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24438 }
24439
24440 test_300g() {
24441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24442         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24443                 skip "Need MDS version at least 2.7.55"
24444
24445         local dir
24446         local stripe_count
24447         local stripe_index
24448
24449         mkdir_on_mdt0 $DIR/$tdir
24450         mkdir $DIR/$tdir/normal_dir
24451
24452         #Checking when client cache stripe index
24453         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24454         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24455                 error "create striped_dir failed"
24456
24457         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24458                 error "create dir0 fails"
24459         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24460         [ $stripe_index -eq 0 ] ||
24461                 error "dir0 expect index 0 got $stripe_index"
24462
24463         mkdir $DIR/$tdir/striped_dir/dir1 ||
24464                 error "create dir1 fails"
24465         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24466         [ $stripe_index -eq 1 ] ||
24467                 error "dir1 expect index 1 got $stripe_index"
24468
24469         #check default stripe count/stripe index
24470         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24471         test_300_check_default_striped_dir normal_dir 1 0
24472         test_300_check_default_striped_dir normal_dir -1 1
24473         test_300_check_default_striped_dir normal_dir 2 -1
24474
24475         #delete default stripe information
24476         echo "delete default stripeEA"
24477         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24478                 error "set default stripe on striped dir error"
24479
24480         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24481         for dir in $(find $DIR/$tdir/normal_dir/*); do
24482                 stripe_count=$($LFS getdirstripe -c $dir)
24483                 [ $stripe_count -eq 0 ] ||
24484                         error "expect 1 get $stripe_count for $dir"
24485         done
24486 }
24487 run_test 300g "check default striped directory for normal directory"
24488
24489 test_300h() {
24490         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24491         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24492                 skip "Need MDS version at least 2.7.55"
24493
24494         local dir
24495         local stripe_count
24496
24497         mkdir $DIR/$tdir
24498         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24499                 error "set striped dir error"
24500
24501         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24502         test_300_check_default_striped_dir striped_dir 1 0
24503         test_300_check_default_striped_dir striped_dir -1 1
24504         test_300_check_default_striped_dir striped_dir 2 -1
24505
24506         #delete default stripe information
24507         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24508                 error "set default stripe on striped dir error"
24509
24510         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24511         for dir in $(find $DIR/$tdir/striped_dir/*); do
24512                 stripe_count=$($LFS getdirstripe -c $dir)
24513                 [ $stripe_count -eq 0 ] ||
24514                         error "expect 1 get $stripe_count for $dir"
24515         done
24516 }
24517 run_test 300h "check default striped directory for striped directory"
24518
24519 test_300i() {
24520         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24521         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24522         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24523                 skip "Need MDS version at least 2.7.55"
24524
24525         local stripe_count
24526         local file
24527
24528         mkdir $DIR/$tdir
24529
24530         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24531                 error "set striped dir error"
24532
24533         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24534                 error "create files under striped dir failed"
24535
24536         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24537                 error "set striped hashdir error"
24538
24539         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24540                 error "create dir0 under hash dir failed"
24541         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24542                 error "create dir1 under hash dir failed"
24543         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24544                 error "create dir2 under hash dir failed"
24545
24546         # unfortunately, we need to umount to clear dir layout cache for now
24547         # once we fully implement dir layout, we can drop this
24548         umount_client $MOUNT || error "umount failed"
24549         mount_client $MOUNT || error "mount failed"
24550
24551         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24552         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24553         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24554
24555         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24556                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24557                         error "create crush2 dir $tdir/hashdir/d3 failed"
24558                 $LFS find -H crush2 $DIR/$tdir/hashdir
24559                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24560                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24561
24562                 # mkdir with an invalid hash type (hash=fail_val) from client
24563                 # should be replaced on MDS with a valid (default) hash type
24564                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24565                 $LCTL set_param fail_loc=0x1901 fail_val=99
24566                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24567
24568                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24569                 local expect=$(do_facet mds1 \
24570                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24571                 [[ $hash == $expect ]] ||
24572                         error "d99 hash '$hash' != expected hash '$expect'"
24573         fi
24574
24575         #set the stripe to be unknown hash type on read
24576         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24577         $LCTL set_param fail_loc=0x1901 fail_val=99
24578         for ((i = 0; i < 10; i++)); do
24579                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24580                         error "stat f-$i failed"
24581                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24582         done
24583
24584         touch $DIR/$tdir/striped_dir/f0 &&
24585                 error "create under striped dir with unknown hash should fail"
24586
24587         $LCTL set_param fail_loc=0
24588
24589         umount_client $MOUNT || error "umount failed"
24590         mount_client $MOUNT || error "mount failed"
24591
24592         return 0
24593 }
24594 run_test 300i "client handle unknown hash type striped directory"
24595
24596 test_300j() {
24597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24599         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24600                 skip "Need MDS version at least 2.7.55"
24601
24602         local stripe_count
24603         local file
24604
24605         mkdir $DIR/$tdir
24606
24607         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24608         $LCTL set_param fail_loc=0x1702
24609         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24610                 error "set striped dir error"
24611
24612         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24613                 error "create files under striped dir failed"
24614
24615         $LCTL set_param fail_loc=0
24616
24617         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24618
24619         return 0
24620 }
24621 run_test 300j "test large update record"
24622
24623 test_300k() {
24624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24625         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24626         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24627                 skip "Need MDS version at least 2.7.55"
24628
24629         # this test needs a huge transaction
24630         local kb
24631         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24632              osd*.$FSNAME-MDT0000.kbytestotal")
24633         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24634
24635         local stripe_count
24636         local file
24637
24638         mkdir $DIR/$tdir
24639
24640         #define OBD_FAIL_LARGE_STRIPE   0x1703
24641         $LCTL set_param fail_loc=0x1703
24642         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24643                 error "set striped dir error"
24644         $LCTL set_param fail_loc=0
24645
24646         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24647                 error "getstripeddir fails"
24648         rm -rf $DIR/$tdir/striped_dir ||
24649                 error "unlink striped dir fails"
24650
24651         return 0
24652 }
24653 run_test 300k "test large striped directory"
24654
24655 test_300l() {
24656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24658         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24659                 skip "Need MDS version at least 2.7.55"
24660
24661         local stripe_index
24662
24663         test_mkdir -p $DIR/$tdir/striped_dir
24664         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24665                         error "chown $RUNAS_ID failed"
24666         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24667                 error "set default striped dir failed"
24668
24669         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24670         $LCTL set_param fail_loc=0x80000158
24671         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24672
24673         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24674         [ $stripe_index -eq 1 ] ||
24675                 error "expect 1 get $stripe_index for $dir"
24676 }
24677 run_test 300l "non-root user to create dir under striped dir with stale layout"
24678
24679 test_300m() {
24680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24681         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24682         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24683                 skip "Need MDS version at least 2.7.55"
24684
24685         mkdir -p $DIR/$tdir/striped_dir
24686         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24687                 error "set default stripes dir error"
24688
24689         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24690
24691         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24692         [ $stripe_count -eq 0 ] ||
24693                         error "expect 0 get $stripe_count for a"
24694
24695         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24696                 error "set default stripes dir error"
24697
24698         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24699
24700         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24701         [ $stripe_count -eq 0 ] ||
24702                         error "expect 0 get $stripe_count for b"
24703
24704         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24705                 error "set default stripes dir error"
24706
24707         mkdir $DIR/$tdir/striped_dir/c &&
24708                 error "default stripe_index is invalid, mkdir c should fails"
24709
24710         rm -rf $DIR/$tdir || error "rmdir fails"
24711 }
24712 run_test 300m "setstriped directory on single MDT FS"
24713
24714 cleanup_300n() {
24715         local list=$(comma_list $(mdts_nodes))
24716
24717         trap 0
24718         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24719 }
24720
24721 test_300n() {
24722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24724         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24725                 skip "Need MDS version at least 2.7.55"
24726         remote_mds_nodsh && skip "remote MDS with nodsh"
24727
24728         local stripe_index
24729         local list=$(comma_list $(mdts_nodes))
24730
24731         trap cleanup_300n RETURN EXIT
24732         mkdir -p $DIR/$tdir
24733         chmod 777 $DIR/$tdir
24734         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24735                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24736                 error "create striped dir succeeds with gid=0"
24737
24738         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24739         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24740                 error "create striped dir fails with gid=-1"
24741
24742         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24743         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24744                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24745                 error "set default striped dir succeeds with gid=0"
24746
24747
24748         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24749         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24750                 error "set default striped dir fails with gid=-1"
24751
24752
24753         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24754         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24755                                         error "create test_dir fails"
24756         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24757                                         error "create test_dir1 fails"
24758         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24759                                         error "create test_dir2 fails"
24760         cleanup_300n
24761 }
24762 run_test 300n "non-root user to create dir under striped dir with default EA"
24763
24764 test_300o() {
24765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24766         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24767         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24768                 skip "Need MDS version at least 2.7.55"
24769
24770         local numfree1
24771         local numfree2
24772
24773         mkdir -p $DIR/$tdir
24774
24775         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24776         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24777         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24778                 skip "not enough free inodes $numfree1 $numfree2"
24779         fi
24780
24781         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24782         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24783         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24784                 skip "not enough free space $numfree1 $numfree2"
24785         fi
24786
24787         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24788                 error "setdirstripe fails"
24789
24790         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24791                 error "create dirs fails"
24792
24793         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24794         ls $DIR/$tdir/striped_dir > /dev/null ||
24795                 error "ls striped dir fails"
24796         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24797                 error "unlink big striped dir fails"
24798 }
24799 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24800
24801 test_300p() {
24802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24804         remote_mds_nodsh && skip "remote MDS with nodsh"
24805
24806         mkdir_on_mdt0 $DIR/$tdir
24807
24808         #define OBD_FAIL_OUT_ENOSPC     0x1704
24809         do_facet mds2 lctl set_param fail_loc=0x80001704
24810         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24811                  && error "create striped directory should fail"
24812
24813         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24814
24815         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24816         true
24817 }
24818 run_test 300p "create striped directory without space"
24819
24820 test_300q() {
24821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24823
24824         local fd=$(free_fd)
24825         local cmd="exec $fd<$tdir"
24826         cd $DIR
24827         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24828         eval $cmd
24829         cmd="exec $fd<&-"
24830         trap "eval $cmd" EXIT
24831         cd $tdir || error "cd $tdir fails"
24832         rmdir  ../$tdir || error "rmdir $tdir fails"
24833         mkdir local_dir && error "create dir succeeds"
24834         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24835         eval $cmd
24836         return 0
24837 }
24838 run_test 300q "create remote directory under orphan directory"
24839
24840 test_300r() {
24841         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24842                 skip "Need MDS version at least 2.7.55" && return
24843         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24844
24845         mkdir $DIR/$tdir
24846
24847         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24848                 error "set striped dir error"
24849
24850         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24851                 error "getstripeddir fails"
24852
24853         local stripe_count
24854         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24855                       awk '/lmv_stripe_count:/ { print $2 }')
24856
24857         [ $MDSCOUNT -ne $stripe_count ] &&
24858                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24859
24860         rm -rf $DIR/$tdir/striped_dir ||
24861                 error "unlink striped dir fails"
24862 }
24863 run_test 300r "test -1 striped directory"
24864
24865 test_300s_helper() {
24866         local count=$1
24867
24868         local stripe_dir=$DIR/$tdir/striped_dir.$count
24869
24870         $LFS mkdir -c $count $stripe_dir ||
24871                 error "lfs mkdir -c error"
24872
24873         $LFS getdirstripe $stripe_dir ||
24874                 error "lfs getdirstripe fails"
24875
24876         local stripe_count
24877         stripe_count=$($LFS getdirstripe $stripe_dir |
24878                       awk '/lmv_stripe_count:/ { print $2 }')
24879
24880         [ $count -ne $stripe_count ] &&
24881                 error_noexit "bad stripe count $stripe_count expected $count"
24882
24883         local dupe_stripes
24884         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24885                 awk '/0x/ {count[$1] += 1}; END {
24886                         for (idx in count) {
24887                                 if (count[idx]>1) {
24888                                         print "index " idx " count " count[idx]
24889                                 }
24890                         }
24891                 }')
24892
24893         if [[ -n "$dupe_stripes" ]] ; then
24894                 lfs getdirstripe $stripe_dir
24895                 error_noexit "Dupe MDT above: $dupe_stripes "
24896         fi
24897
24898         rm -rf $stripe_dir ||
24899                 error_noexit "unlink $stripe_dir fails"
24900 }
24901
24902 test_300s() {
24903         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24904                 skip "Need MDS version at least 2.7.55" && return
24905         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24906
24907         mkdir $DIR/$tdir
24908         for count in $(seq 2 $MDSCOUNT); do
24909                 test_300s_helper $count
24910         done
24911 }
24912 run_test 300s "test lfs mkdir -c without -i"
24913
24914 test_300t() {
24915         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24916                 skip "need MDS 2.14.55 or later"
24917         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24918
24919         local testdir="$DIR/$tdir/striped_dir"
24920         local dir1=$testdir/dir1
24921         local dir2=$testdir/dir2
24922
24923         mkdir -p $testdir
24924
24925         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24926                 error "failed to set default stripe count for $testdir"
24927
24928         mkdir $dir1
24929         local stripe_count=$($LFS getdirstripe -c $dir1)
24930
24931         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24932
24933         local max_count=$((MDSCOUNT - 1))
24934         local mdts=$(comma_list $(mdts_nodes))
24935
24936         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24937         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24938
24939         mkdir $dir2
24940         stripe_count=$($LFS getdirstripe -c $dir2)
24941
24942         (( $stripe_count == $max_count )) || error "wrong stripe count"
24943 }
24944 run_test 300t "test max_mdt_stripecount"
24945
24946 prepare_remote_file() {
24947         mkdir $DIR/$tdir/src_dir ||
24948                 error "create remote source failed"
24949
24950         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24951                  error "cp to remote source failed"
24952         touch $DIR/$tdir/src_dir/a
24953
24954         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24955                 error "create remote target dir failed"
24956
24957         touch $DIR/$tdir/tgt_dir/b
24958
24959         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24960                 error "rename dir cross MDT failed!"
24961
24962         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24963                 error "src_child still exists after rename"
24964
24965         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24966                 error "missing file(a) after rename"
24967
24968         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24969                 error "diff after rename"
24970 }
24971
24972 test_310a() {
24973         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24975
24976         local remote_file=$DIR/$tdir/tgt_dir/b
24977
24978         mkdir -p $DIR/$tdir
24979
24980         prepare_remote_file || error "prepare remote file failed"
24981
24982         #open-unlink file
24983         $OPENUNLINK $remote_file $remote_file ||
24984                 error "openunlink $remote_file failed"
24985         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24986 }
24987 run_test 310a "open unlink remote file"
24988
24989 test_310b() {
24990         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24992
24993         local remote_file=$DIR/$tdir/tgt_dir/b
24994
24995         mkdir -p $DIR/$tdir
24996
24997         prepare_remote_file || error "prepare remote file failed"
24998
24999         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25000         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25001         $CHECKSTAT -t file $remote_file || error "check file failed"
25002 }
25003 run_test 310b "unlink remote file with multiple links while open"
25004
25005 test_310c() {
25006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25007         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25008
25009         local remote_file=$DIR/$tdir/tgt_dir/b
25010
25011         mkdir -p $DIR/$tdir
25012
25013         prepare_remote_file || error "prepare remote file failed"
25014
25015         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25016         multiop_bg_pause $remote_file O_uc ||
25017                         error "mulitop failed for remote file"
25018         MULTIPID=$!
25019         $MULTIOP $DIR/$tfile Ouc
25020         kill -USR1 $MULTIPID
25021         wait $MULTIPID
25022 }
25023 run_test 310c "open-unlink remote file with multiple links"
25024
25025 #LU-4825
25026 test_311() {
25027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25028         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25029         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25030                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25031         remote_mds_nodsh && skip "remote MDS with nodsh"
25032
25033         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25034         local mdts=$(comma_list $(mdts_nodes))
25035
25036         mkdir -p $DIR/$tdir
25037         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25038         createmany -o $DIR/$tdir/$tfile. 1000
25039
25040         # statfs data is not real time, let's just calculate it
25041         old_iused=$((old_iused + 1000))
25042
25043         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25044                         osp.*OST0000*MDT0000.create_count")
25045         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25046                                 osp.*OST0000*MDT0000.max_create_count")
25047         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25048
25049         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25050         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25051         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25052
25053         unlinkmany $DIR/$tdir/$tfile. 1000
25054
25055         do_nodes $mdts "$LCTL set_param -n \
25056                         osp.*OST0000*.max_create_count=$max_count"
25057         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25058                 do_nodes $mdts "$LCTL set_param -n \
25059                                 osp.*OST0000*.create_count=$count"
25060         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25061                         grep "=0" && error "create_count is zero"
25062
25063         local new_iused
25064         for i in $(seq 120); do
25065                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25066                 # system may be too busy to destroy all objs in time, use
25067                 # a somewhat small value to not fail autotest
25068                 [ $((old_iused - new_iused)) -gt 400 ] && break
25069                 sleep 1
25070         done
25071
25072         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25073         [ $((old_iused - new_iused)) -gt 400 ] ||
25074                 error "objs not destroyed after unlink"
25075 }
25076 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25077
25078 zfs_get_objid()
25079 {
25080         local ost=$1
25081         local tf=$2
25082         local fid=($($LFS getstripe $tf | grep 0x))
25083         local seq=${fid[3]#0x}
25084         local objid=${fid[1]}
25085
25086         local vdevdir=$(dirname $(facet_vdevice $ost))
25087         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25088         local zfs_zapid=$(do_facet $ost $cmd |
25089                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25090                           awk '/Object/{getline; print $1}')
25091         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25092                           awk "/$objid = /"'{printf $3}')
25093
25094         echo $zfs_objid
25095 }
25096
25097 zfs_object_blksz() {
25098         local ost=$1
25099         local objid=$2
25100
25101         local vdevdir=$(dirname $(facet_vdevice $ost))
25102         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25103         local blksz=$(do_facet $ost $cmd $objid |
25104                       awk '/dblk/{getline; printf $4}')
25105
25106         case "${blksz: -1}" in
25107                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25108                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25109                 *) ;;
25110         esac
25111
25112         echo $blksz
25113 }
25114
25115 test_312() { # LU-4856
25116         remote_ost_nodsh && skip "remote OST with nodsh"
25117         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25118
25119         local max_blksz=$(do_facet ost1 \
25120                           $ZFS get -p recordsize $(facet_device ost1) |
25121                           awk '!/VALUE/{print $3}')
25122         local tf=$DIR/$tfile
25123
25124         $LFS setstripe -c1 $tf
25125         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25126
25127         # Get ZFS object id
25128         local zfs_objid=$(zfs_get_objid $facet $tf)
25129         # block size change by sequential overwrite
25130         local bs
25131
25132         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25133                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25134
25135                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25136                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25137         done
25138         rm -f $tf
25139
25140         $LFS setstripe -c1 $tf
25141         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25142
25143         # block size change by sequential append write
25144         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25145         zfs_objid=$(zfs_get_objid $facet $tf)
25146         local count
25147
25148         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25149                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25150                         oflag=sync conv=notrunc
25151
25152                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25153                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25154                         error "blksz error, actual $blksz, " \
25155                                 "expected: 2 * $count * $PAGE_SIZE"
25156         done
25157         rm -f $tf
25158
25159         # random write
25160         $LFS setstripe -c1 $tf
25161         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25162         zfs_objid=$(zfs_get_objid $facet $tf)
25163
25164         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25165         blksz=$(zfs_object_blksz $facet $zfs_objid)
25166         (( blksz == PAGE_SIZE )) ||
25167                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25168
25169         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25170         blksz=$(zfs_object_blksz $facet $zfs_objid)
25171         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25172
25173         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25174         blksz=$(zfs_object_blksz $facet $zfs_objid)
25175         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25176 }
25177 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25178
25179 test_313() {
25180         remote_ost_nodsh && skip "remote OST with nodsh"
25181
25182         local file=$DIR/$tfile
25183
25184         rm -f $file
25185         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25186
25187         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25188         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25189         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25190                 error "write should failed"
25191         do_facet ost1 "$LCTL set_param fail_loc=0"
25192         rm -f $file
25193 }
25194 run_test 313 "io should fail after last_rcvd update fail"
25195
25196 test_314() {
25197         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25198
25199         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25200         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25201         rm -f $DIR/$tfile
25202         wait_delete_completed
25203         do_facet ost1 "$LCTL set_param fail_loc=0"
25204 }
25205 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25206
25207 test_315() { # LU-618
25208         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25209
25210         local file=$DIR/$tfile
25211         rm -f $file
25212
25213         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25214                 error "multiop file write failed"
25215         $MULTIOP $file oO_RDONLY:r4063232_c &
25216         PID=$!
25217
25218         sleep 2
25219
25220         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25221         kill -USR1 $PID
25222
25223         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25224         rm -f $file
25225 }
25226 run_test 315 "read should be accounted"
25227
25228 test_316() {
25229         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25230         large_xattr_enabled || skip "ea_inode feature disabled"
25231
25232         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25233         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25234         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25235         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25236
25237         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25238 }
25239 run_test 316 "lfs migrate of file with large_xattr enabled"
25240
25241 test_317() {
25242         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25243                 skip "Need MDS version at least 2.11.53"
25244         if [ "$ost1_FSTYPE" == "zfs" ]; then
25245                 skip "LU-10370: no implementation for ZFS"
25246         fi
25247
25248         local trunc_sz
25249         local grant_blk_size
25250
25251         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25252                         awk '/grant_block_size:/ { print $2; exit; }')
25253         #
25254         # Create File of size 5M. Truncate it to below size's and verify
25255         # blocks count.
25256         #
25257         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25258                 error "Create file $DIR/$tfile failed"
25259         stack_trap "rm -f $DIR/$tfile" EXIT
25260
25261         for trunc_sz in 2097152 4097 4000 509 0; do
25262                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25263                         error "truncate $tfile to $trunc_sz failed"
25264                 local sz=$(stat --format=%s $DIR/$tfile)
25265                 local blk=$(stat --format=%b $DIR/$tfile)
25266                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25267                                      grant_blk_size) * 8))
25268
25269                 if [[ $blk -ne $trunc_blk ]]; then
25270                         $(which stat) $DIR/$tfile
25271                         error "Expected Block $trunc_blk got $blk for $tfile"
25272                 fi
25273
25274                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25275                         error "Expected Size $trunc_sz got $sz for $tfile"
25276         done
25277
25278         #
25279         # sparse file test
25280         # Create file with a hole and write actual 65536 bytes which aligned
25281         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25282         #
25283         local bs=65536
25284         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25285                 error "Create file : $DIR/$tfile"
25286
25287         #
25288         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25289         # blocks. The block count must drop to 8.
25290         #
25291         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25292                 ((bs - grant_blk_size) + 1)))
25293         $TRUNCATE $DIR/$tfile $trunc_sz ||
25294                 error "truncate $tfile to $trunc_sz failed"
25295
25296         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25297         sz=$(stat --format=%s $DIR/$tfile)
25298         blk=$(stat --format=%b $DIR/$tfile)
25299
25300         if [[ $blk -ne $trunc_bsz ]]; then
25301                 $(which stat) $DIR/$tfile
25302                 error "Expected Block $trunc_bsz got $blk for $tfile"
25303         fi
25304
25305         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25306                 error "Expected Size $trunc_sz got $sz for $tfile"
25307 }
25308 run_test 317 "Verify blocks get correctly update after truncate"
25309
25310 test_318() {
25311         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25312         local old_max_active=$($LCTL get_param -n \
25313                             ${llite_name}.max_read_ahead_async_active \
25314                             2>/dev/null)
25315
25316         $LCTL set_param llite.*.max_read_ahead_async_active=256
25317         local max_active=$($LCTL get_param -n \
25318                            ${llite_name}.max_read_ahead_async_active \
25319                            2>/dev/null)
25320         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25321
25322         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25323                 error "set max_read_ahead_async_active should succeed"
25324
25325         $LCTL set_param llite.*.max_read_ahead_async_active=512
25326         max_active=$($LCTL get_param -n \
25327                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25328         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25329
25330         # restore @max_active
25331         [ $old_max_active -ne 0 ] && $LCTL set_param \
25332                 llite.*.max_read_ahead_async_active=$old_max_active
25333
25334         local old_threshold=$($LCTL get_param -n \
25335                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25336         local max_per_file_mb=$($LCTL get_param -n \
25337                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25338
25339         local invalid=$(($max_per_file_mb + 1))
25340         $LCTL set_param \
25341                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25342                         && error "set $invalid should fail"
25343
25344         local valid=$(($invalid - 1))
25345         $LCTL set_param \
25346                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25347                         error "set $valid should succeed"
25348         local threshold=$($LCTL get_param -n \
25349                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25350         [ $threshold -eq $valid ] || error \
25351                 "expect threshold $valid got $threshold"
25352         $LCTL set_param \
25353                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25354 }
25355 run_test 318 "Verify async readahead tunables"
25356
25357 test_319() {
25358         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25359
25360         local before=$(date +%s)
25361         local evict
25362         local mdir=$DIR/$tdir
25363         local file=$mdir/xxx
25364
25365         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25366         touch $file
25367
25368 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25369         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25370         $LFS migrate -m1 $mdir &
25371
25372         sleep 1
25373         dd if=$file of=/dev/null
25374         wait
25375         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25376           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25377
25378         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25379 }
25380 run_test 319 "lost lease lock on migrate error"
25381
25382 test_398a() { # LU-4198
25383         local ost1_imp=$(get_osc_import_name client ost1)
25384         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25385                          cut -d'.' -f2)
25386
25387         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25388         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25389
25390         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25391         # request a new lock on client
25392         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25393
25394         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25395         #local lock_count=$($LCTL get_param -n \
25396         #                  ldlm.namespaces.$imp_name.lru_size)
25397         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25398
25399         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25400
25401         # no lock cached, should use lockless DIO and not enqueue new lock
25402         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25403                 conv=notrunc ||
25404                 error "dio write failed"
25405         lock_count=$($LCTL get_param -n \
25406                      ldlm.namespaces.$imp_name.lru_size)
25407         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25408
25409         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25410
25411         # no lock cached, should use locked DIO append
25412         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25413                 conv=notrunc || error "DIO append failed"
25414         lock_count=$($LCTL get_param -n \
25415                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25416         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25417 }
25418 run_test 398a "direct IO should cancel lock otherwise lockless"
25419
25420 test_398b() { # LU-4198
25421         local before=$(date +%s)
25422         local njobs=4
25423         local size=48
25424
25425         which fio || skip_env "no fio installed"
25426         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25428
25429         # Single page, multiple pages, stripe size, 4*stripe size
25430         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25431                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25432                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25433                         --numjobs=$njobs --fallocate=none \
25434                         --iodepth=16 --allow_file_create=0 \
25435                         --size=$((size/njobs))M \
25436                         --filename=$DIR/$tfile &
25437                 bg_pid=$!
25438
25439                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25440                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25441                         --numjobs=$njobs --fallocate=none \
25442                         --iodepth=16 --allow_file_create=0 \
25443                         --size=$((size/njobs))M \
25444                         --filename=$DIR/$tfile || true
25445                 wait $bg_pid
25446         done
25447
25448         evict=$(do_facet client $LCTL get_param \
25449                 osc.$FSNAME-OST*-osc-*/state |
25450             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25451
25452         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25453                 (do_facet client $LCTL get_param \
25454                         osc.$FSNAME-OST*-osc-*/state;
25455                     error "eviction happened: $evict before:$before")
25456
25457         rm -f $DIR/$tfile
25458 }
25459 run_test 398b "DIO and buffer IO race"
25460
25461 test_398c() { # LU-4198
25462         local ost1_imp=$(get_osc_import_name client ost1)
25463         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25464                          cut -d'.' -f2)
25465
25466         which fio || skip_env "no fio installed"
25467
25468         saved_debug=$($LCTL get_param -n debug)
25469         $LCTL set_param debug=0
25470
25471         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25472         ((size /= 1024)) # by megabytes
25473         ((size /= 2)) # write half of the OST at most
25474         [ $size -gt 40 ] && size=40 #reduce test time anyway
25475
25476         $LFS setstripe -c 1 $DIR/$tfile
25477
25478         # it seems like ldiskfs reserves more space than necessary if the
25479         # writing blocks are not mapped, so it extends the file firstly
25480         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25481         cancel_lru_locks osc
25482
25483         # clear and verify rpc_stats later
25484         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25485
25486         local njobs=4
25487         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25488         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25489                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25490                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25491                 --filename=$DIR/$tfile
25492         [ $? -eq 0 ] || error "fio write error"
25493
25494         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25495                 error "Locks were requested while doing AIO"
25496
25497         # get the percentage of 1-page I/O
25498         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25499                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25500                 awk '{print $7}')
25501         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25502
25503         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25504         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25505                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25506                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25507                 --filename=$DIR/$tfile
25508         [ $? -eq 0 ] || error "fio mixed read write error"
25509
25510         echo "AIO with large block size ${size}M"
25511         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25512                 --numjobs=1 --fallocate=none --ioengine=libaio \
25513                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25514                 --filename=$DIR/$tfile
25515         [ $? -eq 0 ] || error "fio large block size failed"
25516
25517         rm -f $DIR/$tfile
25518         $LCTL set_param debug="$saved_debug"
25519 }
25520 run_test 398c "run fio to test AIO"
25521
25522 test_398d() { #  LU-13846
25523         which aiocp || skip_env "no aiocp installed"
25524         local aio_file=$DIR/$tfile.aio
25525
25526         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25527
25528         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25529         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25530         stack_trap "rm -f $DIR/$tfile $aio_file"
25531
25532         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25533
25534         # make sure we don't crash and fail properly
25535         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25536                 error "aio not aligned with PAGE SIZE should fail"
25537
25538         rm -f $DIR/$tfile $aio_file
25539 }
25540 run_test 398d "run aiocp to verify block size > stripe size"
25541
25542 test_398e() {
25543         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25544         touch $DIR/$tfile.new
25545         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25546 }
25547 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25548
25549 test_398f() { #  LU-14687
25550         which aiocp || skip_env "no aiocp installed"
25551         local aio_file=$DIR/$tfile.aio
25552
25553         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25554
25555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25556         stack_trap "rm -f $DIR/$tfile $aio_file"
25557
25558         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25559         $LCTL set_param fail_loc=0x1418
25560         # make sure we don't crash and fail properly
25561         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25562                 error "aio with page allocation failure succeeded"
25563         $LCTL set_param fail_loc=0
25564         diff $DIR/$tfile $aio_file
25565         [[ $? != 0 ]] || error "no diff after failed aiocp"
25566 }
25567 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25568
25569 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25570 # stripe and i/o size must be > stripe size
25571 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25572 # single RPC in flight.  This test shows async DIO submission is working by
25573 # showing multiple RPCs in flight.
25574 test_398g() { #  LU-13798
25575         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25576
25577         # We need to do some i/o first to acquire enough grant to put our RPCs
25578         # in flight; otherwise a new connection may not have enough grant
25579         # available
25580         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25581                 error "parallel dio failed"
25582         stack_trap "rm -f $DIR/$tfile"
25583
25584         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25585         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25586         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25587         stack_trap "$LCTL set_param -n $pages_per_rpc"
25588
25589         # Recreate file so it's empty
25590         rm -f $DIR/$tfile
25591         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25592         #Pause rpc completion to guarantee we see multiple rpcs in flight
25593         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25594         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25595         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25596
25597         # Clear rpc stats
25598         $LCTL set_param osc.*.rpc_stats=c
25599
25600         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25601                 error "parallel dio failed"
25602         stack_trap "rm -f $DIR/$tfile"
25603
25604         $LCTL get_param osc.*-OST0000-*.rpc_stats
25605         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25606                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25607                 grep "8:" | awk '{print $8}')
25608         # We look at the "8 rpcs in flight" field, and verify A) it is present
25609         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25610         # as expected for an 8M DIO to a file with 1M stripes.
25611         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25612
25613         # Verify turning off parallel dio works as expected
25614         # Clear rpc stats
25615         $LCTL set_param osc.*.rpc_stats=c
25616         $LCTL set_param llite.*.parallel_dio=0
25617         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25618
25619         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25620                 error "dio with parallel dio disabled failed"
25621
25622         # Ideally, we would see only one RPC in flight here, but there is an
25623         # unavoidable race between i/o completion and RPC in flight counting,
25624         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25625         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25626         # So instead we just verify it's always < 8.
25627         $LCTL get_param osc.*-OST0000-*.rpc_stats
25628         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25629                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25630                 grep '^$' -B1 | grep . | awk '{print $1}')
25631         [ $ret != "8:" ] ||
25632                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25633 }
25634 run_test 398g "verify parallel dio async RPC submission"
25635
25636 test_398h() { #  LU-13798
25637         local dio_file=$DIR/$tfile.dio
25638
25639         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25640
25641         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25642         stack_trap "rm -f $DIR/$tfile $dio_file"
25643
25644         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25645                 error "parallel dio failed"
25646         diff $DIR/$tfile $dio_file
25647         [[ $? == 0 ]] || error "file diff after aiocp"
25648 }
25649 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25650
25651 test_398i() { #  LU-13798
25652         local dio_file=$DIR/$tfile.dio
25653
25654         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25655
25656         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25657         stack_trap "rm -f $DIR/$tfile $dio_file"
25658
25659         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25660         $LCTL set_param fail_loc=0x1418
25661         # make sure we don't crash and fail properly
25662         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25663                 error "parallel dio page allocation failure succeeded"
25664         diff $DIR/$tfile $dio_file
25665         [[ $? != 0 ]] || error "no diff after failed aiocp"
25666 }
25667 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25668
25669 test_398j() { #  LU-13798
25670         # Stripe size > RPC size but less than i/o size tests split across
25671         # stripes and RPCs for individual i/o op
25672         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25673
25674         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25675         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25676         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25677         stack_trap "$LCTL set_param -n $pages_per_rpc"
25678
25679         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25680                 error "parallel dio write failed"
25681         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25682
25683         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25684                 error "parallel dio read failed"
25685         diff $DIR/$tfile $DIR/$tfile.2
25686         [[ $? == 0 ]] || error "file diff after parallel dio read"
25687 }
25688 run_test 398j "test parallel dio where stripe size > rpc_size"
25689
25690 test_398k() { #  LU-13798
25691         wait_delete_completed
25692         wait_mds_ost_sync
25693
25694         # 4 stripe file; we will cause out of space on OST0
25695         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25696
25697         # Fill OST0 (if it's not too large)
25698         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25699                    head -n1)
25700         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25701                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25702         fi
25703         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25704         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25705                 error "dd should fill OST0"
25706         stack_trap "rm -f $DIR/$tfile.1"
25707
25708         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25709         err=$?
25710
25711         ls -la $DIR/$tfile
25712         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25713                 error "file is not 0 bytes in size"
25714
25715         # dd above should not succeed, but don't error until here so we can
25716         # get debug info above
25717         [[ $err != 0 ]] ||
25718                 error "parallel dio write with enospc succeeded"
25719         stack_trap "rm -f $DIR/$tfile"
25720 }
25721 run_test 398k "test enospc on first stripe"
25722
25723 test_398l() { #  LU-13798
25724         wait_delete_completed
25725         wait_mds_ost_sync
25726
25727         # 4 stripe file; we will cause out of space on OST0
25728         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25729         # happens on the second i/o chunk we issue
25730         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25731
25732         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25733         stack_trap "rm -f $DIR/$tfile"
25734
25735         # Fill OST0 (if it's not too large)
25736         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25737                    head -n1)
25738         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25739                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25740         fi
25741         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25742         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25743                 error "dd should fill OST0"
25744         stack_trap "rm -f $DIR/$tfile.1"
25745
25746         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25747         err=$?
25748         stack_trap "rm -f $DIR/$tfile.2"
25749
25750         # Check that short write completed as expected
25751         ls -la $DIR/$tfile.2
25752         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25753                 error "file is not 1M in size"
25754
25755         # dd above should not succeed, but don't error until here so we can
25756         # get debug info above
25757         [[ $err != 0 ]] ||
25758                 error "parallel dio write with enospc succeeded"
25759
25760         # Truncate source file to same length as output file and diff them
25761         $TRUNCATE $DIR/$tfile 1048576
25762         diff $DIR/$tfile $DIR/$tfile.2
25763         [[ $? == 0 ]] || error "data incorrect after short write"
25764 }
25765 run_test 398l "test enospc on intermediate stripe/RPC"
25766
25767 test_398m() { #  LU-13798
25768         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25769
25770         # Set up failure on OST0, the first stripe:
25771         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25772         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25773         # OST0 is on ost1, OST1 is on ost2.
25774         # So this fail_val specifies OST0
25775         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25776         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25777
25778         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25779                 error "parallel dio write with failure on first stripe succeeded"
25780         stack_trap "rm -f $DIR/$tfile"
25781         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25782
25783         # Place data in file for read
25784         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25785                 error "parallel dio write failed"
25786
25787         # Fail read on OST0, first stripe
25788         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25789         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25790         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25791                 error "parallel dio read with error on first stripe succeeded"
25792         rm -f $DIR/$tfile.2
25793         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25794
25795         # Switch to testing on OST1, second stripe
25796         # Clear file contents, maintain striping
25797         echo > $DIR/$tfile
25798         # Set up failure on OST1, second stripe:
25799         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25800         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25801
25802         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25803                 error "parallel dio write with failure on second stripe succeeded"
25804         stack_trap "rm -f $DIR/$tfile"
25805         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25806
25807         # Place data in file for read
25808         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25809                 error "parallel dio write failed"
25810
25811         # Fail read on OST1, second stripe
25812         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25813         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25814         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25815                 error "parallel dio read with error on second stripe succeeded"
25816         rm -f $DIR/$tfile.2
25817         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25818 }
25819 run_test 398m "test RPC failures with parallel dio"
25820
25821 # Parallel submission of DIO should not cause problems for append, but it's
25822 # important to verify.
25823 test_398n() { #  LU-13798
25824         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25825
25826         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25827                 error "dd to create source file failed"
25828         stack_trap "rm -f $DIR/$tfile"
25829
25830         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25831                 error "parallel dio write with failure on second stripe succeeded"
25832         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25833         diff $DIR/$tfile $DIR/$tfile.1
25834         [[ $? == 0 ]] || error "data incorrect after append"
25835
25836 }
25837 run_test 398n "test append with parallel DIO"
25838
25839 test_398o() {
25840         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25841 }
25842 run_test 398o "right kms with DIO"
25843
25844 test_fake_rw() {
25845         local read_write=$1
25846         if [ "$read_write" = "write" ]; then
25847                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25848         elif [ "$read_write" = "read" ]; then
25849                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25850         else
25851                 error "argument error"
25852         fi
25853
25854         # turn off debug for performance testing
25855         local saved_debug=$($LCTL get_param -n debug)
25856         $LCTL set_param debug=0
25857
25858         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25859
25860         # get ost1 size - $FSNAME-OST0000
25861         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25862         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25863         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25864
25865         if [ "$read_write" = "read" ]; then
25866                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25867         fi
25868
25869         local start_time=$(date +%s.%N)
25870         $dd_cmd bs=1M count=$blocks oflag=sync ||
25871                 error "real dd $read_write error"
25872         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25873
25874         if [ "$read_write" = "write" ]; then
25875                 rm -f $DIR/$tfile
25876         fi
25877
25878         # define OBD_FAIL_OST_FAKE_RW           0x238
25879         do_facet ost1 $LCTL set_param fail_loc=0x238
25880
25881         local start_time=$(date +%s.%N)
25882         $dd_cmd bs=1M count=$blocks oflag=sync ||
25883                 error "fake dd $read_write error"
25884         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25885
25886         if [ "$read_write" = "write" ]; then
25887                 # verify file size
25888                 cancel_lru_locks osc
25889                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25890                         error "$tfile size not $blocks MB"
25891         fi
25892         do_facet ost1 $LCTL set_param fail_loc=0
25893
25894         echo "fake $read_write $duration_fake vs. normal $read_write" \
25895                 "$duration in seconds"
25896         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25897                 error_not_in_vm "fake write is slower"
25898
25899         $LCTL set_param -n debug="$saved_debug"
25900         rm -f $DIR/$tfile
25901 }
25902 test_399a() { # LU-7655 for OST fake write
25903         remote_ost_nodsh && skip "remote OST with nodsh"
25904
25905         test_fake_rw write
25906 }
25907 run_test 399a "fake write should not be slower than normal write"
25908
25909 test_399b() { # LU-8726 for OST fake read
25910         remote_ost_nodsh && skip "remote OST with nodsh"
25911         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25912                 skip_env "ldiskfs only test"
25913         fi
25914
25915         test_fake_rw read
25916 }
25917 run_test 399b "fake read should not be slower than normal read"
25918
25919 test_400a() { # LU-1606, was conf-sanity test_74
25920         if ! which $CC > /dev/null 2>&1; then
25921                 skip_env "$CC is not installed"
25922         fi
25923
25924         local extra_flags=''
25925         local out=$TMP/$tfile
25926         local prefix=/usr/include/lustre
25927         local prog
25928
25929         # Oleg removes .c files in his test rig so test if any c files exist
25930         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25931                 skip_env "Needed .c test files are missing"
25932
25933         if ! [[ -d $prefix ]]; then
25934                 # Assume we're running in tree and fixup the include path.
25935                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25936                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25937                 extra_flags+=" -L$LUSTRE/utils/.libs"
25938         fi
25939
25940         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25941                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25942                         error "client api broken"
25943         done
25944         rm -f $out
25945 }
25946 run_test 400a "Lustre client api program can compile and link"
25947
25948 test_400b() { # LU-1606, LU-5011
25949         local header
25950         local out=$TMP/$tfile
25951         local prefix=/usr/include/linux/lustre
25952
25953         # We use a hard coded prefix so that this test will not fail
25954         # when run in tree. There are headers in lustre/include/lustre/
25955         # that are not packaged (like lustre_idl.h) and have more
25956         # complicated include dependencies (like config.h and lnet/types.h).
25957         # Since this test about correct packaging we just skip them when
25958         # they don't exist (see below) rather than try to fixup cppflags.
25959
25960         if ! which $CC > /dev/null 2>&1; then
25961                 skip_env "$CC is not installed"
25962         fi
25963
25964         for header in $prefix/*.h; do
25965                 if ! [[ -f "$header" ]]; then
25966                         continue
25967                 fi
25968
25969                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25970                         continue # lustre_ioctl.h is internal header
25971                 fi
25972
25973                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25974                         error "cannot compile '$header'"
25975         done
25976         rm -f $out
25977 }
25978 run_test 400b "packaged headers can be compiled"
25979
25980 test_401a() { #LU-7437
25981         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25982         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25983
25984         #count the number of parameters by "list_param -R"
25985         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25986         #count the number of parameters by listing proc files
25987         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25988         echo "proc_dirs='$proc_dirs'"
25989         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25990         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25991                       sort -u | wc -l)
25992
25993         [ $params -eq $procs ] ||
25994                 error "found $params parameters vs. $procs proc files"
25995
25996         # test the list_param -D option only returns directories
25997         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25998         #count the number of parameters by listing proc directories
25999         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26000                 sort -u | wc -l)
26001
26002         [ $params -eq $procs ] ||
26003                 error "found $params parameters vs. $procs proc files"
26004 }
26005 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26006
26007 test_401b() {
26008         # jobid_var may not allow arbitrary values, so use jobid_name
26009         # if available
26010         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26011                 local testname=jobid_name tmp='testing%p'
26012         else
26013                 local testname=jobid_var tmp=testing
26014         fi
26015
26016         local save=$($LCTL get_param -n $testname)
26017
26018         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26019                 error "no error returned when setting bad parameters"
26020
26021         local jobid_new=$($LCTL get_param -n foe $testname baz)
26022         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26023
26024         $LCTL set_param -n fog=bam $testname=$save bat=fog
26025         local jobid_old=$($LCTL get_param -n foe $testname bag)
26026         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26027 }
26028 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26029
26030 test_401c() {
26031         # jobid_var may not allow arbitrary values, so use jobid_name
26032         # if available
26033         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26034                 local testname=jobid_name
26035         else
26036                 local testname=jobid_var
26037         fi
26038
26039         local jobid_var_old=$($LCTL get_param -n $testname)
26040         local jobid_var_new
26041
26042         $LCTL set_param $testname= &&
26043                 error "no error returned for 'set_param a='"
26044
26045         jobid_var_new=$($LCTL get_param -n $testname)
26046         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26047                 error "$testname was changed by setting without value"
26048
26049         $LCTL set_param $testname &&
26050                 error "no error returned for 'set_param a'"
26051
26052         jobid_var_new=$($LCTL get_param -n $testname)
26053         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26054                 error "$testname was changed by setting without value"
26055 }
26056 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26057
26058 test_401d() {
26059         # jobid_var may not allow arbitrary values, so use jobid_name
26060         # if available
26061         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26062                 local testname=jobid_name new_value='foo=bar%p'
26063         else
26064                 local testname=jobid_var new_valuie=foo=bar
26065         fi
26066
26067         local jobid_var_old=$($LCTL get_param -n $testname)
26068         local jobid_var_new
26069
26070         $LCTL set_param $testname=$new_value ||
26071                 error "'set_param a=b' did not accept a value containing '='"
26072
26073         jobid_var_new=$($LCTL get_param -n $testname)
26074         [[ "$jobid_var_new" == "$new_value" ]] ||
26075                 error "'set_param a=b' failed on a value containing '='"
26076
26077         # Reset the $testname to test the other format
26078         $LCTL set_param $testname=$jobid_var_old
26079         jobid_var_new=$($LCTL get_param -n $testname)
26080         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26081                 error "failed to reset $testname"
26082
26083         $LCTL set_param $testname $new_value ||
26084                 error "'set_param a b' did not accept a value containing '='"
26085
26086         jobid_var_new=$($LCTL get_param -n $testname)
26087         [[ "$jobid_var_new" == "$new_value" ]] ||
26088                 error "'set_param a b' failed on a value containing '='"
26089
26090         $LCTL set_param $testname $jobid_var_old
26091         jobid_var_new=$($LCTL get_param -n $testname)
26092         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26093                 error "failed to reset $testname"
26094 }
26095 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26096
26097 test_401e() { # LU-14779
26098         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26099                 error "lctl list_param MGC* failed"
26100         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26101         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26102                 error "lctl get_param lru_size failed"
26103 }
26104 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26105
26106 test_402() {
26107         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26108         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26109                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26110         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26111                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26112                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26113         remote_mds_nodsh && skip "remote MDS with nodsh"
26114
26115         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26116 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26117         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26118         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26119                 echo "Touch failed - OK"
26120 }
26121 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26122
26123 test_403() {
26124         local file1=$DIR/$tfile.1
26125         local file2=$DIR/$tfile.2
26126         local tfile=$TMP/$tfile
26127
26128         rm -f $file1 $file2 $tfile
26129
26130         touch $file1
26131         ln $file1 $file2
26132
26133         # 30 sec OBD_TIMEOUT in ll_getattr()
26134         # right before populating st_nlink
26135         $LCTL set_param fail_loc=0x80001409
26136         stat -c %h $file1 > $tfile &
26137
26138         # create an alias, drop all locks and reclaim the dentry
26139         < $file2
26140         cancel_lru_locks mdc
26141         cancel_lru_locks osc
26142         sysctl -w vm.drop_caches=2
26143
26144         wait
26145
26146         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26147
26148         rm -f $tfile $file1 $file2
26149 }
26150 run_test 403 "i_nlink should not drop to zero due to aliasing"
26151
26152 test_404() { # LU-6601
26153         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26154                 skip "Need server version newer than 2.8.52"
26155         remote_mds_nodsh && skip "remote MDS with nodsh"
26156
26157         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26158                 awk '/osp .*-osc-MDT/ { print $4}')
26159
26160         local osp
26161         for osp in $mosps; do
26162                 echo "Deactivate: " $osp
26163                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26164                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26165                         awk -vp=$osp '$4 == p { print $2 }')
26166                 [ $stat = IN ] || {
26167                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26168                         error "deactivate error"
26169                 }
26170                 echo "Activate: " $osp
26171                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26172                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26173                         awk -vp=$osp '$4 == p { print $2 }')
26174                 [ $stat = UP ] || {
26175                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26176                         error "activate error"
26177                 }
26178         done
26179 }
26180 run_test 404 "validate manual {de}activated works properly for OSPs"
26181
26182 test_405() {
26183         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26184         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26185                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26186                         skip "Layout swap lock is not supported"
26187
26188         check_swap_layouts_support
26189         check_swap_layout_no_dom $DIR
26190
26191         test_mkdir $DIR/$tdir
26192         swap_lock_test -d $DIR/$tdir ||
26193                 error "One layout swap locked test failed"
26194 }
26195 run_test 405 "Various layout swap lock tests"
26196
26197 test_406() {
26198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26199         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26200         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26202         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26203                 skip "Need MDS version at least 2.8.50"
26204
26205         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26206         local test_pool=$TESTNAME
26207
26208         pool_add $test_pool || error "pool_add failed"
26209         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26210                 error "pool_add_targets failed"
26211
26212         save_layout_restore_at_exit $MOUNT
26213
26214         # parent set default stripe count only, child will stripe from both
26215         # parent and fs default
26216         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26217                 error "setstripe $MOUNT failed"
26218         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26219         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26220         for i in $(seq 10); do
26221                 local f=$DIR/$tdir/$tfile.$i
26222                 touch $f || error "touch failed"
26223                 local count=$($LFS getstripe -c $f)
26224                 [ $count -eq $OSTCOUNT ] ||
26225                         error "$f stripe count $count != $OSTCOUNT"
26226                 local offset=$($LFS getstripe -i $f)
26227                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26228                 local size=$($LFS getstripe -S $f)
26229                 [ $size -eq $((def_stripe_size * 2)) ] ||
26230                         error "$f stripe size $size != $((def_stripe_size * 2))"
26231                 local pool=$($LFS getstripe -p $f)
26232                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26233         done
26234
26235         # change fs default striping, delete parent default striping, now child
26236         # will stripe from new fs default striping only
26237         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26238                 error "change $MOUNT default stripe failed"
26239         $LFS setstripe -c 0 $DIR/$tdir ||
26240                 error "delete $tdir default stripe failed"
26241         for i in $(seq 11 20); do
26242                 local f=$DIR/$tdir/$tfile.$i
26243                 touch $f || error "touch $f failed"
26244                 local count=$($LFS getstripe -c $f)
26245                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26246                 local offset=$($LFS getstripe -i $f)
26247                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26248                 local size=$($LFS getstripe -S $f)
26249                 [ $size -eq $def_stripe_size ] ||
26250                         error "$f stripe size $size != $def_stripe_size"
26251                 local pool=$($LFS getstripe -p $f)
26252                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26253         done
26254
26255         unlinkmany $DIR/$tdir/$tfile. 1 20
26256
26257         local f=$DIR/$tdir/$tfile
26258         pool_remove_all_targets $test_pool $f
26259         pool_remove $test_pool $f
26260 }
26261 run_test 406 "DNE support fs default striping"
26262
26263 test_407() {
26264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26265         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26266                 skip "Need MDS version at least 2.8.55"
26267         remote_mds_nodsh && skip "remote MDS with nodsh"
26268
26269         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26270                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26271         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26272                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26273         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26274
26275         #define OBD_FAIL_DT_TXN_STOP    0x2019
26276         for idx in $(seq $MDSCOUNT); do
26277                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26278         done
26279         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26280         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26281                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26282         true
26283 }
26284 run_test 407 "transaction fail should cause operation fail"
26285
26286 test_408() {
26287         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26288
26289         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26290         lctl set_param fail_loc=0x8000040a
26291         # let ll_prepare_partial_page() fail
26292         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26293
26294         rm -f $DIR/$tfile
26295
26296         # create at least 100 unused inodes so that
26297         # shrink_icache_memory(0) should not return 0
26298         touch $DIR/$tfile-{0..100}
26299         rm -f $DIR/$tfile-{0..100}
26300         sync
26301
26302         echo 2 > /proc/sys/vm/drop_caches
26303 }
26304 run_test 408 "drop_caches should not hang due to page leaks"
26305
26306 test_409()
26307 {
26308         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26309
26310         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26311         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26312         touch $DIR/$tdir/guard || error "(2) Fail to create"
26313
26314         local PREFIX=$(str_repeat 'A' 128)
26315         echo "Create 1K hard links start at $(date)"
26316         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26317                 error "(3) Fail to hard link"
26318
26319         echo "Links count should be right although linkEA overflow"
26320         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26321         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26322         [ $linkcount -eq 1001 ] ||
26323                 error "(5) Unexpected hard links count: $linkcount"
26324
26325         echo "List all links start at $(date)"
26326         ls -l $DIR/$tdir/foo > /dev/null ||
26327                 error "(6) Fail to list $DIR/$tdir/foo"
26328
26329         echo "Unlink hard links start at $(date)"
26330         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26331                 error "(7) Fail to unlink"
26332         echo "Unlink hard links finished at $(date)"
26333 }
26334 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26335
26336 test_410()
26337 {
26338         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26339                 skip "Need client version at least 2.9.59"
26340         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26341                 skip "Need MODULES build"
26342
26343         # Create a file, and stat it from the kernel
26344         local testfile=$DIR/$tfile
26345         touch $testfile
26346
26347         local run_id=$RANDOM
26348         local my_ino=$(stat --format "%i" $testfile)
26349
26350         # Try to insert the module. This will always fail as the
26351         # module is designed to not be inserted.
26352         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26353             &> /dev/null
26354
26355         # Anything but success is a test failure
26356         dmesg | grep -q \
26357             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26358             error "no inode match"
26359 }
26360 run_test 410 "Test inode number returned from kernel thread"
26361
26362 cleanup_test411_cgroup() {
26363         trap 0
26364         rmdir "$1"
26365 }
26366
26367 test_411() {
26368         local cg_basedir=/sys/fs/cgroup/memory
26369         # LU-9966
26370         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26371                 skip "no setup for cgroup"
26372
26373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26374                 error "test file creation failed"
26375         cancel_lru_locks osc
26376
26377         # Create a very small memory cgroup to force a slab allocation error
26378         local cgdir=$cg_basedir/osc_slab_alloc
26379         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26380         trap "cleanup_test411_cgroup $cgdir" EXIT
26381         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26382         echo 1M > $cgdir/memory.limit_in_bytes
26383
26384         # Should not LBUG, just be killed by oom-killer
26385         # dd will return 0 even allocation failure in some environment.
26386         # So don't check return value
26387         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26388         cleanup_test411_cgroup $cgdir
26389
26390         return 0
26391 }
26392 run_test 411 "Slab allocation error with cgroup does not LBUG"
26393
26394 test_412() {
26395         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26396         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26397                 skip "Need server version at least 2.10.55"
26398
26399         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26400                 error "mkdir failed"
26401         $LFS getdirstripe $DIR/$tdir
26402         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26403         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26404                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26405         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26406         [ $stripe_count -eq 2 ] ||
26407                 error "expect 2 get $stripe_count"
26408
26409         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26410
26411         local index
26412         local index2
26413
26414         # subdirs should be on the same MDT as parent
26415         for i in $(seq 0 $((MDSCOUNT - 1))); do
26416                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26417                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26418                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26419                 (( index == i )) || error "mdt$i/sub on MDT$index"
26420         done
26421
26422         # stripe offset -1, ditto
26423         for i in {1..10}; do
26424                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26425                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26426                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26427                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26428                 (( index == index2 )) ||
26429                         error "qos$i on MDT$index, sub on MDT$index2"
26430         done
26431
26432         local testdir=$DIR/$tdir/inherit
26433
26434         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26435         # inherit 2 levels
26436         for i in 1 2; do
26437                 testdir=$testdir/s$i
26438                 mkdir $testdir || error "mkdir $testdir failed"
26439                 index=$($LFS getstripe -m $testdir)
26440                 (( index == 1 )) ||
26441                         error "$testdir on MDT$index"
26442         done
26443
26444         # not inherit any more
26445         testdir=$testdir/s3
26446         mkdir $testdir || error "mkdir $testdir failed"
26447         getfattr -d -m dmv $testdir | grep dmv &&
26448                 error "default LMV set on $testdir" || true
26449 }
26450 run_test 412 "mkdir on specific MDTs"
26451
26452 TEST413_COUNT=${TEST413_COUNT:-200}
26453
26454 #
26455 # set_maxage() is used by test_413 only.
26456 # This is a helper function to set maxage. Does not return any value.
26457 # Input: maxage to set
26458 #
26459 set_maxage() {
26460         local lmv_qos_maxage
26461         local lod_qos_maxage
26462         local new_maxage=$1
26463
26464         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26465         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26466         stack_trap "$LCTL set_param \
26467                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26468         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26469                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26470         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26471                 lod.*.mdt_qos_maxage=$new_maxage
26472         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26473                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26474 }
26475
26476 generate_uneven_mdts() {
26477         local threshold=$1
26478         local ffree
26479         local bavail
26480         local max
26481         local min
26482         local max_index
26483         local min_index
26484         local tmp
26485         local i
26486
26487         echo
26488         echo "Check for uneven MDTs: "
26489
26490         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26491         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26492         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26493
26494         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26495         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26496         max_index=0
26497         min_index=0
26498         for ((i = 1; i < ${#ffree[@]}; i++)); do
26499                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26500                 if [ $tmp -gt $max ]; then
26501                         max=$tmp
26502                         max_index=$i
26503                 fi
26504                 if [ $tmp -lt $min ]; then
26505                         min=$tmp
26506                         min_index=$i
26507                 fi
26508         done
26509
26510         (( min > 0 )) || skip "low space on MDT$min_index"
26511         (( ${ffree[min_index]} > 0 )) ||
26512                 skip "no free files on MDT$min_index"
26513         (( ${ffree[min_index]} < 10000000 )) ||
26514                 skip "too many free files on MDT$min_index"
26515
26516         # Check if we need to generate uneven MDTs
26517         local diff=$(((max - min) * 100 / min))
26518         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26519         local testdir # individual folder within $testdirp
26520         local start
26521         local cmd
26522
26523         # fallocate is faster to consume space on MDT, if available
26524         if check_fallocate_supported mds$((min_index + 1)); then
26525                 cmd="fallocate -l 128K "
26526         else
26527                 cmd="dd if=/dev/zero bs=128K count=1 of="
26528         fi
26529
26530         echo "using cmd $cmd"
26531         for (( i = 0; diff < threshold; i++ )); do
26532                 testdir=${testdirp}/$i
26533                 [ -d $testdir ] && continue
26534
26535                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26536
26537                 mkdir -p $testdirp
26538                 # generate uneven MDTs, create till $threshold% diff
26539                 echo -n "weight diff=$diff% must be > $threshold% ..."
26540                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26541                 $LFS mkdir -i $min_index $testdir ||
26542                         error "mkdir $testdir failed"
26543                 $LFS setstripe -E 1M -L mdt $testdir ||
26544                         error "setstripe $testdir failed"
26545                 start=$SECONDS
26546                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26547                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26548                 done
26549                 sync; sleep 1; sync
26550
26551                 # wait for QOS to update
26552                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26553
26554                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26555                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26556                 max=$(((${ffree[max_index]} >> 8) *
26557                         (${bavail[max_index]} * bsize >> 16)))
26558                 min=$(((${ffree[min_index]} >> 8) *
26559                         (${bavail[min_index]} * bsize >> 16)))
26560                 (( min > 0 )) || skip "low space on MDT$min_index"
26561                 diff=$(((max - min) * 100 / min))
26562         done
26563
26564         echo "MDT filesfree available: ${ffree[*]}"
26565         echo "MDT blocks available: ${bavail[*]}"
26566         echo "weight diff=$diff%"
26567 }
26568
26569 test_qos_mkdir() {
26570         local mkdir_cmd=$1
26571         local stripe_count=$2
26572         local mdts=$(comma_list $(mdts_nodes))
26573
26574         local testdir
26575         local lmv_qos_prio_free
26576         local lmv_qos_threshold_rr
26577         local lod_qos_prio_free
26578         local lod_qos_threshold_rr
26579         local total
26580         local count
26581         local i
26582
26583         # @total is total directories created if it's testing plain
26584         # directories, otherwise it's total stripe object count for
26585         # striped directories test.
26586         # remote/striped directory unlinking is slow on zfs and may
26587         # timeout, test with fewer directories
26588         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26589
26590         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26591         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26592         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26593                 head -n1)
26594         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26595         stack_trap "$LCTL set_param \
26596                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26597         stack_trap "$LCTL set_param \
26598                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26599
26600         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26601                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26602         lod_qos_prio_free=${lod_qos_prio_free%%%}
26603         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26604                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26605         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26606         stack_trap "do_nodes $mdts $LCTL set_param \
26607                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26608         stack_trap "do_nodes $mdts $LCTL set_param \
26609                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26610
26611         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26612         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26613
26614         testdir=$DIR/$tdir-s$stripe_count/rr
26615
26616         local stripe_index=$($LFS getstripe -m $testdir)
26617         local test_mkdir_rr=true
26618
26619         getfattr -d -m dmv -e hex $testdir | grep dmv
26620         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26621                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26622                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26623                         test_mkdir_rr=false
26624         fi
26625
26626         echo
26627         $test_mkdir_rr &&
26628                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26629                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26630
26631         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26632         for (( i = 0; i < total / stripe_count; i++ )); do
26633                 eval $mkdir_cmd $testdir/subdir$i ||
26634                         error "$mkdir_cmd subdir$i failed"
26635         done
26636
26637         for (( i = 0; i < $MDSCOUNT; i++ )); do
26638                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26639                 echo "$count directories created on MDT$i"
26640                 if $test_mkdir_rr; then
26641                         (( count == total / stripe_count / MDSCOUNT )) ||
26642                                 error "subdirs are not evenly distributed"
26643                 elif (( i == stripe_index )); then
26644                         (( count == total / stripe_count )) ||
26645                                 error "$count subdirs created on MDT$i"
26646                 else
26647                         (( count == 0 )) ||
26648                                 error "$count subdirs created on MDT$i"
26649                 fi
26650
26651                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26652                         count=$($LFS getdirstripe $testdir/* |
26653                                 grep -c -P "^\s+$i\t")
26654                         echo "$count stripes created on MDT$i"
26655                         # deviation should < 5% of average
26656                         delta=$((count - total / MDSCOUNT))
26657                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26658                                 error "stripes are not evenly distributed"
26659                 fi
26660         done
26661
26662         echo
26663         echo "Check for uneven MDTs: "
26664
26665         local ffree
26666         local bavail
26667         local max
26668         local min
26669         local max_index
26670         local min_index
26671         local tmp
26672
26673         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26674         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26675         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26676
26677         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26678         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26679         max_index=0
26680         min_index=0
26681         for ((i = 1; i < ${#ffree[@]}; i++)); do
26682                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26683                 if [ $tmp -gt $max ]; then
26684                         max=$tmp
26685                         max_index=$i
26686                 fi
26687                 if [ $tmp -lt $min ]; then
26688                         min=$tmp
26689                         min_index=$i
26690                 fi
26691         done
26692         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26693
26694         (( min > 0 )) || skip "low space on MDT$min_index"
26695         (( ${ffree[min_index]} < 10000000 )) ||
26696                 skip "too many free files on MDT$min_index"
26697
26698         generate_uneven_mdts 120
26699
26700         echo "MDT filesfree available: ${ffree[*]}"
26701         echo "MDT blocks available: ${bavail[*]}"
26702         echo "weight diff=$(((max - min) * 100 / min))%"
26703         echo
26704         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26705
26706         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26707         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26708         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26709         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26710         # decrease statfs age, so that it can be updated in time
26711         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26712         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26713
26714         sleep 1
26715
26716         testdir=$DIR/$tdir-s$stripe_count/qos
26717
26718         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26719         for (( i = 0; i < total / stripe_count; i++ )); do
26720                 eval $mkdir_cmd $testdir/subdir$i ||
26721                         error "$mkdir_cmd subdir$i failed"
26722         done
26723
26724         max=0
26725         for (( i = 0; i < $MDSCOUNT; i++ )); do
26726                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26727                 (( count > max )) && max=$count
26728                 echo "$count directories created on MDT$i : curmax=$max"
26729         done
26730
26731         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26732
26733         # D-value should > 10% of average
26734         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26735                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26736
26737         # ditto for stripes
26738         if (( stripe_count > 1 )); then
26739                 max=0
26740                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26741                         count=$($LFS getdirstripe $testdir/* |
26742                                 grep -c -P "^\s+$i\t")
26743                         (( count > max )) && max=$count
26744                         echo "$count stripes created on MDT$i"
26745                 done
26746
26747                 min=$($LFS getdirstripe $testdir/* |
26748                         grep -c -P "^\s+$min_index\t")
26749                 (( max - min > total / MDSCOUNT / 10 )) ||
26750                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26751         fi
26752 }
26753
26754 most_full_mdt() {
26755         local ffree
26756         local bavail
26757         local bsize
26758         local min
26759         local min_index
26760         local tmp
26761
26762         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26763         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26764         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26765
26766         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26767         min_index=0
26768         for ((i = 1; i < ${#ffree[@]}; i++)); do
26769                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26770                 (( tmp < min )) && min=$tmp && min_index=$i
26771         done
26772
26773         echo -n $min_index
26774 }
26775
26776 test_413a() {
26777         [ $MDSCOUNT -lt 2 ] &&
26778                 skip "We need at least 2 MDTs for this test"
26779
26780         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26781                 skip "Need server version at least 2.12.52"
26782
26783         local stripe_max=$((MDSCOUNT - 1))
26784         local stripe_count
26785
26786         # let caller set maxage for latest result
26787         set_maxage 1
26788
26789         # fill MDT unevenly
26790         generate_uneven_mdts 120
26791
26792         # test 4-stripe directory at most, otherwise it's too slow
26793         # We are being very defensive. Although Autotest uses 4 MDTs.
26794         # We make sure stripe_max does not go over 4.
26795         (( stripe_max > 4 )) && stripe_max=4
26796         # unlinking striped directory is slow on zfs, and may timeout, only test
26797         # plain directory
26798         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26799         for stripe_count in $(seq 1 $stripe_max); do
26800                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26801                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26802                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26803                         error "mkdir failed"
26804                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26805         done
26806 }
26807 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26808
26809 test_413b() {
26810         [ $MDSCOUNT -lt 2 ] &&
26811                 skip "We need at least 2 MDTs for this test"
26812
26813         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26814                 skip "Need server version at least 2.12.52"
26815
26816         local stripe_max=$((MDSCOUNT - 1))
26817         local testdir
26818         local stripe_count
26819
26820         # let caller set maxage for latest result
26821         set_maxage 1
26822
26823         # fill MDT unevenly
26824         generate_uneven_mdts 120
26825
26826         # test 4-stripe directory at most, otherwise it's too slow
26827         # We are being very defensive. Although Autotest uses 4 MDTs.
26828         # We make sure stripe_max does not go over 4.
26829         (( stripe_max > 4 )) && stripe_max=4
26830         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26831         for stripe_count in $(seq 1 $stripe_max); do
26832                 testdir=$DIR/$tdir-s$stripe_count
26833                 mkdir $testdir || error "mkdir $testdir failed"
26834                 mkdir $testdir/rr || error "mkdir rr failed"
26835                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26836                         error "mkdir qos failed"
26837                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26838                         $testdir/rr || error "setdirstripe rr failed"
26839                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26840                         error "setdirstripe failed"
26841                 test_qos_mkdir "mkdir" $stripe_count
26842         done
26843 }
26844 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26845
26846 test_413c() {
26847         (( $MDSCOUNT >= 2 )) ||
26848                 skip "We need at least 2 MDTs for this test"
26849
26850         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26851                 skip "Need server version at least 2.14.51"
26852
26853         local testdir
26854         local inherit
26855         local inherit_rr
26856         local lmv_qos_maxage
26857         local lod_qos_maxage
26858
26859         # let caller set maxage for latest result
26860         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26861         $LCTL set_param lmv.*.qos_maxage=1
26862         stack_trap "$LCTL set_param \
26863                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26864         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26865                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26866         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26867                 lod.*.mdt_qos_maxage=1
26868         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26869                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26870
26871         # fill MDT unevenly
26872         generate_uneven_mdts 120
26873
26874         testdir=$DIR/${tdir}-s1
26875         mkdir $testdir || error "mkdir $testdir failed"
26876         mkdir $testdir/rr || error "mkdir rr failed"
26877         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26878         # default max_inherit is -1, default max_inherit_rr is 0
26879         $LFS setdirstripe -D -c 1 $testdir/rr ||
26880                 error "setdirstripe rr failed"
26881         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26882                 error "setdirstripe qos failed"
26883         test_qos_mkdir "mkdir" 1
26884
26885         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26886         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26887         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26888         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26889         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26890
26891         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26892         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26893         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26894         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26895         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26896         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26897         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26898                 error "level2 shouldn't have default LMV" || true
26899 }
26900 run_test 413c "mkdir with default LMV max inherit rr"
26901
26902 test_413d() {
26903         (( MDSCOUNT >= 2 )) ||
26904                 skip "We need at least 2 MDTs for this test"
26905
26906         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26907                 skip "Need server version at least 2.14.51"
26908
26909         local lmv_qos_threshold_rr
26910
26911         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26912                 head -n1)
26913         stack_trap "$LCTL set_param \
26914                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26915
26916         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26917         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26918         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26919                 error "$tdir shouldn't have default LMV"
26920         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26921                 error "mkdir sub failed"
26922
26923         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26924
26925         (( count == 100 )) || error "$count subdirs on MDT0"
26926 }
26927 run_test 413d "inherit ROOT default LMV"
26928
26929 test_413e() {
26930         (( MDSCOUNT >= 2 )) ||
26931                 skip "We need at least 2 MDTs for this test"
26932         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26933                 skip "Need server version at least 2.14.55"
26934
26935         local testdir=$DIR/$tdir
26936         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26937         local max_inherit
26938         local sub_max_inherit
26939
26940         mkdir -p $testdir || error "failed to create $testdir"
26941
26942         # set default max-inherit to -1 if stripe count is 0 or 1
26943         $LFS setdirstripe -D -c 1 $testdir ||
26944                 error "failed to set default LMV"
26945         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26946         (( max_inherit == -1 )) ||
26947                 error "wrong max_inherit value $max_inherit"
26948
26949         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26950         $LFS setdirstripe -D -c -1 $testdir ||
26951                 error "failed to set default LMV"
26952         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26953         (( max_inherit > 0 )) ||
26954                 error "wrong max_inherit value $max_inherit"
26955
26956         # and the subdir will decrease the max_inherit by 1
26957         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26958         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26959         (( sub_max_inherit == max_inherit - 1)) ||
26960                 error "wrong max-inherit of subdir $sub_max_inherit"
26961
26962         # check specified --max-inherit and warning message
26963         stack_trap "rm -f $tmpfile"
26964         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26965                 error "failed to set default LMV"
26966         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26967         (( max_inherit == -1 )) ||
26968                 error "wrong max_inherit value $max_inherit"
26969
26970         # check the warning messages
26971         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26972                 error "failed to detect warning string"
26973         fi
26974 }
26975 run_test 413e "check default max-inherit value"
26976
26977 test_fs_dmv_inherit()
26978 {
26979         local testdir=$DIR/$tdir
26980
26981         local count
26982         local inherit
26983         local inherit_rr
26984
26985         for i in 1 2; do
26986                 mkdir $testdir || error "mkdir $testdir failed"
26987                 count=$($LFS getdirstripe -D -c $testdir)
26988                 (( count == 1 )) ||
26989                         error "$testdir default LMV count mismatch $count != 1"
26990                 inherit=$($LFS getdirstripe -D -X $testdir)
26991                 (( inherit == 3 - i )) ||
26992                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26993                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26994                 (( inherit_rr == 3 - i )) ||
26995                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26996                 testdir=$testdir/sub
26997         done
26998
26999         mkdir $testdir || error "mkdir $testdir failed"
27000         count=$($LFS getdirstripe -D -c $testdir)
27001         (( count == 0 )) ||
27002                 error "$testdir default LMV count not zero: $count"
27003 }
27004
27005 test_413f() {
27006         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27007
27008         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27009                 skip "Need server version at least 2.14.55"
27010
27011         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27012                 error "dump $DIR default LMV failed"
27013         stack_trap "setfattr --restore=$TMP/dmv.ea"
27014
27015         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27016                 error "set $DIR default LMV failed"
27017
27018         test_fs_dmv_inherit
27019 }
27020 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27021
27022 test_413g() {
27023         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27024
27025         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27026         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27027                 error "dump $DIR default LMV failed"
27028         stack_trap "setfattr --restore=$TMP/dmv.ea"
27029
27030         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27031                 error "set $DIR default LMV failed"
27032
27033         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27034                 error "mount $MOUNT2 failed"
27035         stack_trap "umount_client $MOUNT2"
27036
27037         local saved_DIR=$DIR
27038
27039         export DIR=$MOUNT2
27040
27041         stack_trap "export DIR=$saved_DIR"
27042
27043         # first check filesystem-wide default LMV inheritance
27044         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27045
27046         # then check subdirs are spread to all MDTs
27047         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27048
27049         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27050
27051         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27052 }
27053 run_test 413g "enforce ROOT default LMV on subdir mount"
27054
27055 test_413h() {
27056         (( MDSCOUNT >= 2 )) ||
27057                 skip "We need at least 2 MDTs for this test"
27058
27059         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27060                 skip "Need server version at least 2.15.50.6"
27061
27062         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27063
27064         stack_trap "$LCTL set_param \
27065                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27066         $LCTL set_param lmv.*.qos_maxage=1
27067
27068         local depth=5
27069         local rr_depth=4
27070         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27071         local count=$((MDSCOUNT * 20))
27072
27073         generate_uneven_mdts 50
27074
27075         mkdir -p $dir || error "mkdir $dir failed"
27076         stack_trap "rm -rf $dir"
27077         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27078                 --max-inherit-rr=$rr_depth $dir
27079
27080         for ((d=0; d < depth + 2; d++)); do
27081                 log "dir=$dir:"
27082                 for ((sub=0; sub < count; sub++)); do
27083                         mkdir $dir/d$sub
27084                 done
27085                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27086                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27087                 # subdirs within $rr_depth should be created round-robin
27088                 if (( d < rr_depth )); then
27089                         (( ${num[0]} != count )) ||
27090                                 error "all objects created on MDT ${num[1]}"
27091                 fi
27092
27093                 dir=$dir/d0
27094         done
27095 }
27096 run_test 413h "don't stick to parent for round-robin dirs"
27097
27098 test_413i() {
27099         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27100
27101         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27102                 skip "Need server version at least 2.14.55"
27103
27104         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27105                 error "dump $DIR default LMV failed"
27106         stack_trap "setfattr --restore=$TMP/dmv.ea"
27107
27108         local testdir=$DIR/$tdir
27109         local def_max_rr=1
27110         local def_max=3
27111         local count
27112
27113         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27114                 --max-inherit-rr=$def_max_rr $DIR ||
27115                 error "set $DIR default LMV failed"
27116
27117         for i in $(seq 2 3); do
27118                 def_max=$((def_max - 1))
27119                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27120
27121                 mkdir $testdir
27122                 # RR is decremented and keeps zeroed once exhausted
27123                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27124                 (( count == def_max_rr )) ||
27125                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27126
27127                 # max-inherit is decremented
27128                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27129                 (( count == def_max )) ||
27130                         error_noexit "$testdir: max-inherit $count != $def_max"
27131
27132                 testdir=$testdir/d$i
27133         done
27134
27135         # d3 is the last inherited from ROOT, no inheritance anymore
27136         # i.e. no the default layout anymore
27137         mkdir -p $testdir/d4/d5
27138         count=$($LFS getdirstripe -D --max-inherit $testdir)
27139         (( count == -1 )) ||
27140                 error_noexit "$testdir: max-inherit $count != -1"
27141
27142         local p_count=$($LFS getdirstripe -i $testdir)
27143
27144         for i in $(seq 4 5); do
27145                 testdir=$testdir/d$i
27146
27147                 # the root default layout is not applied once exhausted
27148                 count=$($LFS getdirstripe -i $testdir)
27149                 (( count == p_count )) ||
27150                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27151         done
27152
27153         $LFS setdirstripe -i 0 $DIR/d2
27154         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27155         (( count == -1 )) ||
27156                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27157 }
27158 run_test 413i "check default layout inheritance"
27159
27160 test_413z() {
27161         local pids=""
27162         local subdir
27163         local pid
27164
27165         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27166                 unlinkmany $subdir/f. $TEST413_COUNT &
27167                 pids="$pids $!"
27168         done
27169
27170         for pid in $pids; do
27171                 wait $pid
27172         done
27173
27174         true
27175 }
27176 run_test 413z "413 test cleanup"
27177
27178 test_414() {
27179 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27180         $LCTL set_param fail_loc=0x80000521
27181         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27182         rm -f $DIR/$tfile
27183 }
27184 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27185
27186 test_415() {
27187         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27188         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27189                 skip "Need server version at least 2.11.52"
27190
27191         # LU-11102
27192         local total=500
27193         local max=120
27194
27195         # this test may be slow on ZFS
27196         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27197
27198         # though this test is designed for striped directory, let's test normal
27199         # directory too since lock is always saved as CoS lock.
27200         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27201         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27202         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27203         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27204         wait_delete_completed_mds
27205
27206         # run a loop without concurrent touch to measure rename duration.
27207         # only for test debug/robustness, NOT part of COS functional test.
27208         local start_time=$SECONDS
27209         for ((i = 0; i < total; i++)); do
27210                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27211                         > /dev/null
27212         done
27213         local baseline=$((SECONDS - start_time))
27214         echo "rename $total files without 'touch' took $baseline sec"
27215
27216         (
27217                 while true; do
27218                         touch $DIR/$tdir
27219                 done
27220         ) &
27221         local setattr_pid=$!
27222
27223         # rename files back to original name so unlinkmany works
27224         start_time=$SECONDS
27225         for ((i = 0; i < total; i++)); do
27226                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27227                         > /dev/null
27228         done
27229         local duration=$((SECONDS - start_time))
27230
27231         kill -9 $setattr_pid
27232
27233         echo "rename $total files with 'touch' took $duration sec"
27234         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27235         (( duration <= max )) || error "rename took $duration > $max sec"
27236 }
27237 run_test 415 "lock revoke is not missing"
27238
27239 test_416() {
27240         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27241                 skip "Need server version at least 2.11.55"
27242
27243         # define OBD_FAIL_OSD_TXN_START    0x19a
27244         do_facet mds1 lctl set_param fail_loc=0x19a
27245
27246         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27247
27248         true
27249 }
27250 run_test 416 "transaction start failure won't cause system hung"
27251
27252 cleanup_417() {
27253         trap 0
27254         do_nodes $(comma_list $(mdts_nodes)) \
27255                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27256         do_nodes $(comma_list $(mdts_nodes)) \
27257                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27258         do_nodes $(comma_list $(mdts_nodes)) \
27259                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27260 }
27261
27262 test_417() {
27263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27264         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27265                 skip "Need MDS version at least 2.11.56"
27266
27267         trap cleanup_417 RETURN EXIT
27268
27269         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27270         do_nodes $(comma_list $(mdts_nodes)) \
27271                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27272         $LFS migrate -m 0 $DIR/$tdir.1 &&
27273                 error "migrate dir $tdir.1 should fail"
27274
27275         do_nodes $(comma_list $(mdts_nodes)) \
27276                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27277         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27278                 error "create remote dir $tdir.2 should fail"
27279
27280         do_nodes $(comma_list $(mdts_nodes)) \
27281                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27282         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27283                 error "create striped dir $tdir.3 should fail"
27284         true
27285 }
27286 run_test 417 "disable remote dir, striped dir and dir migration"
27287
27288 # Checks that the outputs of df [-i] and lfs df [-i] match
27289 #
27290 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27291 check_lfs_df() {
27292         local dir=$2
27293         local inodes
27294         local df_out
27295         local lfs_df_out
27296         local count
27297         local passed=false
27298
27299         # blocks or inodes
27300         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27301
27302         for count in {1..100}; do
27303                 do_nodes "$CLIENTS" \
27304                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27305                 sync; sleep 0.2
27306
27307                 # read the lines of interest
27308                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27309                         error "df $inodes $dir | tail -n +2 failed"
27310                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27311                         error "lfs df $inodes $dir | grep summary: failed"
27312
27313                 # skip first substrings of each output as they are different
27314                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27315                 # compare the two outputs
27316                 passed=true
27317                 #  skip "available" on MDT until LU-13997 is fixed.
27318                 #for i in {1..5}; do
27319                 for i in 1 2 4 5; do
27320                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27321                 done
27322                 $passed && break
27323         done
27324
27325         if ! $passed; then
27326                 df -P $inodes $dir
27327                 echo
27328                 lfs df $inodes $dir
27329                 error "df and lfs df $1 output mismatch: "      \
27330                       "df ${inodes}: ${df_out[*]}, "            \
27331                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27332         fi
27333 }
27334
27335 test_418() {
27336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27337
27338         local dir=$DIR/$tdir
27339         local numfiles=$((RANDOM % 4096 + 2))
27340         local numblocks=$((RANDOM % 256 + 1))
27341
27342         wait_delete_completed
27343         test_mkdir $dir
27344
27345         # check block output
27346         check_lfs_df blocks $dir
27347         # check inode output
27348         check_lfs_df inodes $dir
27349
27350         # create a single file and retest
27351         echo "Creating a single file and testing"
27352         createmany -o $dir/$tfile- 1 &>/dev/null ||
27353                 error "creating 1 file in $dir failed"
27354         check_lfs_df blocks $dir
27355         check_lfs_df inodes $dir
27356
27357         # create a random number of files
27358         echo "Creating $((numfiles - 1)) files and testing"
27359         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27360                 error "creating $((numfiles - 1)) files in $dir failed"
27361
27362         # write a random number of blocks to the first test file
27363         echo "Writing $numblocks 4K blocks and testing"
27364         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27365                 count=$numblocks &>/dev/null ||
27366                 error "dd to $dir/${tfile}-0 failed"
27367
27368         # retest
27369         check_lfs_df blocks $dir
27370         check_lfs_df inodes $dir
27371
27372         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27373                 error "unlinking $numfiles files in $dir failed"
27374 }
27375 run_test 418 "df and lfs df outputs match"
27376
27377 test_419()
27378 {
27379         local dir=$DIR/$tdir
27380
27381         mkdir -p $dir
27382         touch $dir/file
27383
27384         cancel_lru_locks mdc
27385
27386         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27387         $LCTL set_param fail_loc=0x1410
27388         cat $dir/file
27389         $LCTL set_param fail_loc=0
27390         rm -rf $dir
27391 }
27392 run_test 419 "Verify open file by name doesn't crash kernel"
27393
27394 test_420()
27395 {
27396         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27397                 skip "Need MDS version at least 2.12.53"
27398
27399         local SAVE_UMASK=$(umask)
27400         local dir=$DIR/$tdir
27401         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27402
27403         mkdir -p $dir
27404         umask 0000
27405         mkdir -m03777 $dir/testdir
27406         ls -dn $dir/testdir
27407         # Need to remove trailing '.' when SELinux is enabled
27408         local dirperms=$(ls -dn $dir/testdir |
27409                          awk '{ sub(/\.$/, "", $1); print $1}')
27410         [ $dirperms == "drwxrwsrwt" ] ||
27411                 error "incorrect perms on $dir/testdir"
27412
27413         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27414                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27415         ls -n $dir/testdir/testfile
27416         local fileperms=$(ls -n $dir/testdir/testfile |
27417                           awk '{ sub(/\.$/, "", $1); print $1}')
27418         [ $fileperms == "-rwxr-xr-x" ] ||
27419                 error "incorrect perms on $dir/testdir/testfile"
27420
27421         umask $SAVE_UMASK
27422 }
27423 run_test 420 "clear SGID bit on non-directories for non-members"
27424
27425 test_421a() {
27426         local cnt
27427         local fid1
27428         local fid2
27429
27430         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27431                 skip "Need MDS version at least 2.12.54"
27432
27433         test_mkdir $DIR/$tdir
27434         createmany -o $DIR/$tdir/f 3
27435         cnt=$(ls -1 $DIR/$tdir | wc -l)
27436         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27437
27438         fid1=$(lfs path2fid $DIR/$tdir/f1)
27439         fid2=$(lfs path2fid $DIR/$tdir/f2)
27440         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27441
27442         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27443         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27444
27445         cnt=$(ls -1 $DIR/$tdir | wc -l)
27446         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27447
27448         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27449         createmany -o $DIR/$tdir/f 3
27450         cnt=$(ls -1 $DIR/$tdir | wc -l)
27451         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27452
27453         fid1=$(lfs path2fid $DIR/$tdir/f1)
27454         fid2=$(lfs path2fid $DIR/$tdir/f2)
27455         echo "remove using fsname $FSNAME"
27456         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27457
27458         cnt=$(ls -1 $DIR/$tdir | wc -l)
27459         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27460 }
27461 run_test 421a "simple rm by fid"
27462
27463 test_421b() {
27464         local cnt
27465         local FID1
27466         local FID2
27467
27468         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27469                 skip "Need MDS version at least 2.12.54"
27470
27471         test_mkdir $DIR/$tdir
27472         createmany -o $DIR/$tdir/f 3
27473         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27474         MULTIPID=$!
27475
27476         FID1=$(lfs path2fid $DIR/$tdir/f1)
27477         FID2=$(lfs path2fid $DIR/$tdir/f2)
27478         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27479
27480         kill -USR1 $MULTIPID
27481         wait
27482
27483         cnt=$(ls $DIR/$tdir | wc -l)
27484         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27485 }
27486 run_test 421b "rm by fid on open file"
27487
27488 test_421c() {
27489         local cnt
27490         local FIDS
27491
27492         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27493                 skip "Need MDS version at least 2.12.54"
27494
27495         test_mkdir $DIR/$tdir
27496         createmany -o $DIR/$tdir/f 3
27497         touch $DIR/$tdir/$tfile
27498         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27499         cnt=$(ls -1 $DIR/$tdir | wc -l)
27500         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27501
27502         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27503         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27504
27505         cnt=$(ls $DIR/$tdir | wc -l)
27506         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27507 }
27508 run_test 421c "rm by fid against hardlinked files"
27509
27510 test_421d() {
27511         local cnt
27512         local FIDS
27513
27514         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27515                 skip "Need MDS version at least 2.12.54"
27516
27517         test_mkdir $DIR/$tdir
27518         createmany -o $DIR/$tdir/f 4097
27519         cnt=$(ls -1 $DIR/$tdir | wc -l)
27520         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27521
27522         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27523         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27524
27525         cnt=$(ls $DIR/$tdir | wc -l)
27526         rm -rf $DIR/$tdir
27527         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27528 }
27529 run_test 421d "rmfid en masse"
27530
27531 test_421e() {
27532         local cnt
27533         local FID
27534
27535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27536         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27537                 skip "Need MDS version at least 2.12.54"
27538
27539         mkdir -p $DIR/$tdir
27540         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27541         createmany -o $DIR/$tdir/striped_dir/f 512
27542         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27543         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27544
27545         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27546                 sed "s/[/][^:]*://g")
27547         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27548
27549         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27550         rm -rf $DIR/$tdir
27551         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27552 }
27553 run_test 421e "rmfid in DNE"
27554
27555 test_421f() {
27556         local cnt
27557         local FID
27558
27559         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27560                 skip "Need MDS version at least 2.12.54"
27561
27562         test_mkdir $DIR/$tdir
27563         touch $DIR/$tdir/f
27564         cnt=$(ls -1 $DIR/$tdir | wc -l)
27565         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27566
27567         FID=$(lfs path2fid $DIR/$tdir/f)
27568         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27569         # rmfid should fail
27570         cnt=$(ls -1 $DIR/$tdir | wc -l)
27571         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27572
27573         chmod a+rw $DIR/$tdir
27574         ls -la $DIR/$tdir
27575         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27576         # rmfid should fail
27577         cnt=$(ls -1 $DIR/$tdir | wc -l)
27578         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27579
27580         rm -f $DIR/$tdir/f
27581         $RUNAS touch $DIR/$tdir/f
27582         FID=$(lfs path2fid $DIR/$tdir/f)
27583         echo "rmfid as root"
27584         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27585         cnt=$(ls -1 $DIR/$tdir | wc -l)
27586         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27587
27588         rm -f $DIR/$tdir/f
27589         $RUNAS touch $DIR/$tdir/f
27590         cnt=$(ls -1 $DIR/$tdir | wc -l)
27591         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27592         FID=$(lfs path2fid $DIR/$tdir/f)
27593         # rmfid w/o user_fid2path mount option should fail
27594         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27595         cnt=$(ls -1 $DIR/$tdir | wc -l)
27596         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27597
27598         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27599         stack_trap "rmdir $tmpdir"
27600         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27601                 error "failed to mount client'"
27602         stack_trap "umount_client $tmpdir"
27603
27604         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27605         # rmfid should succeed
27606         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27607         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27608
27609         # rmfid shouldn't allow to remove files due to dir's permission
27610         chmod a+rwx $tmpdir/$tdir
27611         touch $tmpdir/$tdir/f
27612         ls -la $tmpdir/$tdir
27613         FID=$(lfs path2fid $tmpdir/$tdir/f)
27614         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27615         return 0
27616 }
27617 run_test 421f "rmfid checks permissions"
27618
27619 test_421g() {
27620         local cnt
27621         local FIDS
27622
27623         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27624         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27625                 skip "Need MDS version at least 2.12.54"
27626
27627         mkdir -p $DIR/$tdir
27628         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27629         createmany -o $DIR/$tdir/striped_dir/f 512
27630         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27631         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27632
27633         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27634                 sed "s/[/][^:]*://g")
27635
27636         rm -f $DIR/$tdir/striped_dir/f1*
27637         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27638         removed=$((512 - cnt))
27639
27640         # few files have been just removed, so we expect
27641         # rmfid to fail on their fids
27642         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27643         [ $removed != $errors ] && error "$errors != $removed"
27644
27645         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27646         rm -rf $DIR/$tdir
27647         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27648 }
27649 run_test 421g "rmfid to return errors properly"
27650
27651 test_421h() {
27652         local mount_other
27653         local mount_ret
27654         local rmfid_ret
27655         local old_fid
27656         local fidA
27657         local fidB
27658         local fidC
27659         local fidD
27660
27661         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27662                 skip "Need MDS version at least 2.15.53"
27663
27664         test_mkdir $DIR/$tdir
27665         test_mkdir $DIR/$tdir/subdir
27666         touch $DIR/$tdir/subdir/file0
27667         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27668         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27669         rm -f $DIR/$tdir/subdir/file0
27670         touch $DIR/$tdir/subdir/fileA
27671         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27672         echo File $DIR/$tdir/subdir/fileA FID $fidA
27673         touch $DIR/$tdir/subdir/fileB
27674         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27675         echo File $DIR/$tdir/subdir/fileB FID $fidB
27676         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27677         touch $DIR/$tdir/subdir/fileC
27678         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27679         echo File $DIR/$tdir/subdir/fileC FID $fidC
27680         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27681         touch $DIR/$tdir/fileD
27682         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27683         echo File $DIR/$tdir/fileD FID $fidD
27684
27685         # mount another client mount point with subdirectory mount
27686         export FILESET=/$tdir/subdir
27687         mount_other=${MOUNT}_other
27688         mount_client $mount_other ${MOUNT_OPTS}
27689         mount_ret=$?
27690         export FILESET=""
27691         (( mount_ret == 0 )) || error "mount $mount_other failed"
27692
27693         echo Removing FIDs:
27694         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27695         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27696         rmfid_ret=$?
27697
27698         umount_client $mount_other || error "umount $mount_other failed"
27699
27700         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27701
27702         # fileA should have been deleted
27703         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27704
27705         # fileB should have been deleted
27706         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27707
27708         # fileC should not have been deleted, fid also exists outside of fileset
27709         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27710
27711         # fileD should not have been deleted, it exists outside of fileset
27712         stat $DIR/$tdir/fileD || error "fileD deleted"
27713 }
27714 run_test 421h "rmfid with fileset mount"
27715
27716 test_422() {
27717         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27718         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27719         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27720         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27721         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27722
27723         local amc=$(at_max_get client)
27724         local amo=$(at_max_get mds1)
27725         local timeout=`lctl get_param -n timeout`
27726
27727         at_max_set 0 client
27728         at_max_set 0 mds1
27729
27730 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27731         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27732                         fail_val=$(((2*timeout + 10)*1000))
27733         touch $DIR/$tdir/d3/file &
27734         sleep 2
27735 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27736         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27737                         fail_val=$((2*timeout + 5))
27738         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27739         local pid=$!
27740         sleep 1
27741         kill -9 $pid
27742         sleep $((2 * timeout))
27743         echo kill $pid
27744         kill -9 $pid
27745         lctl mark touch
27746         touch $DIR/$tdir/d2/file3
27747         touch $DIR/$tdir/d2/file4
27748         touch $DIR/$tdir/d2/file5
27749
27750         wait
27751         at_max_set $amc client
27752         at_max_set $amo mds1
27753
27754         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27755         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27756                 error "Watchdog is always throttled"
27757 }
27758 run_test 422 "kill a process with RPC in progress"
27759
27760 stat_test() {
27761     df -h $MOUNT &
27762     df -h $MOUNT &
27763     df -h $MOUNT &
27764     df -h $MOUNT &
27765     df -h $MOUNT &
27766     df -h $MOUNT &
27767 }
27768
27769 test_423() {
27770     local _stats
27771     # ensure statfs cache is expired
27772     sleep 2;
27773
27774     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27775     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27776
27777     return 0
27778 }
27779 run_test 423 "statfs should return a right data"
27780
27781 test_424() {
27782 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27783         $LCTL set_param fail_loc=0x80000522
27784         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27785         rm -f $DIR/$tfile
27786 }
27787 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27788
27789 test_425() {
27790         test_mkdir -c -1 $DIR/$tdir
27791         $LFS setstripe -c -1 $DIR/$tdir
27792
27793         lru_resize_disable "" 100
27794         stack_trap "lru_resize_enable" EXIT
27795
27796         sleep 5
27797
27798         for i in $(seq $((MDSCOUNT * 125))); do
27799                 local t=$DIR/$tdir/$tfile_$i
27800
27801                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27802                         error_noexit "Create file $t"
27803         done
27804         stack_trap "rm -rf $DIR/$tdir" EXIT
27805
27806         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27807                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27808                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27809
27810                 [ $lock_count -le $lru_size ] ||
27811                         error "osc lock count $lock_count > lru size $lru_size"
27812         done
27813
27814         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27815                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27816                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27817
27818                 [ $lock_count -le $lru_size ] ||
27819                         error "mdc lock count $lock_count > lru size $lru_size"
27820         done
27821 }
27822 run_test 425 "lock count should not exceed lru size"
27823
27824 test_426() {
27825         splice-test -r $DIR/$tfile
27826         splice-test -rd $DIR/$tfile
27827         splice-test $DIR/$tfile
27828         splice-test -d $DIR/$tfile
27829 }
27830 run_test 426 "splice test on Lustre"
27831
27832 test_427() {
27833         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27834         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27835                 skip "Need MDS version at least 2.12.4"
27836         local log
27837
27838         mkdir $DIR/$tdir
27839         mkdir $DIR/$tdir/1
27840         mkdir $DIR/$tdir/2
27841         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27842         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27843
27844         $LFS getdirstripe $DIR/$tdir/1/dir
27845
27846         #first setfattr for creating updatelog
27847         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27848
27849 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27850         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27851         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27852         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27853
27854         sleep 2
27855         fail mds2
27856         wait_recovery_complete mds2 $((2*TIMEOUT))
27857
27858         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27859         echo $log | grep "get update log failed" &&
27860                 error "update log corruption is detected" || true
27861 }
27862 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27863
27864 test_428() {
27865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27866         local cache_limit=$CACHE_MAX
27867
27868         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27869         $LCTL set_param -n llite.*.max_cached_mb=64
27870
27871         mkdir $DIR/$tdir
27872         $LFS setstripe -c 1 $DIR/$tdir
27873         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27874         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27875         #test write
27876         for f in $(seq 4); do
27877                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27878         done
27879         wait
27880
27881         cancel_lru_locks osc
27882         # Test read
27883         for f in $(seq 4); do
27884                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27885         done
27886         wait
27887 }
27888 run_test 428 "large block size IO should not hang"
27889
27890 test_429() { # LU-7915 / LU-10948
27891         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27892         local testfile=$DIR/$tfile
27893         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27894         local new_flag=1
27895         local first_rpc
27896         local second_rpc
27897         local third_rpc
27898
27899         $LCTL get_param $ll_opencache_threshold_count ||
27900                 skip "client does not have opencache parameter"
27901
27902         set_opencache $new_flag
27903         stack_trap "restore_opencache"
27904         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27905                 error "enable opencache failed"
27906         touch $testfile
27907         # drop MDC DLM locks
27908         cancel_lru_locks mdc
27909         # clear MDC RPC stats counters
27910         $LCTL set_param $mdc_rpcstats=clear
27911
27912         # According to the current implementation, we need to run 3 times
27913         # open & close file to verify if opencache is enabled correctly.
27914         # 1st, RPCs are sent for lookup/open and open handle is released on
27915         #      close finally.
27916         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27917         #      so open handle won't be released thereafter.
27918         # 3rd, No RPC is sent out.
27919         $MULTIOP $testfile oc || error "multiop failed"
27920         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27921         echo "1st: $first_rpc RPCs in flight"
27922
27923         $MULTIOP $testfile oc || error "multiop failed"
27924         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27925         echo "2nd: $second_rpc RPCs in flight"
27926
27927         $MULTIOP $testfile oc || error "multiop failed"
27928         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27929         echo "3rd: $third_rpc RPCs in flight"
27930
27931         #verify no MDC RPC is sent
27932         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27933 }
27934 run_test 429 "verify if opencache flag on client side does work"
27935
27936 lseek_test_430() {
27937         local offset
27938         local file=$1
27939
27940         # data at [200K, 400K)
27941         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27942                 error "256K->512K dd fails"
27943         # data at [2M, 3M)
27944         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27945                 error "2M->3M dd fails"
27946         # data at [4M, 5M)
27947         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27948                 error "4M->5M dd fails"
27949         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27950         # start at first component hole #1
27951         printf "Seeking hole from 1000 ... "
27952         offset=$(lseek_test -l 1000 $file)
27953         echo $offset
27954         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27955         printf "Seeking data from 1000 ... "
27956         offset=$(lseek_test -d 1000 $file)
27957         echo $offset
27958         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27959
27960         # start at first component data block
27961         printf "Seeking hole from 300000 ... "
27962         offset=$(lseek_test -l 300000 $file)
27963         echo $offset
27964         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27965         printf "Seeking data from 300000 ... "
27966         offset=$(lseek_test -d 300000 $file)
27967         echo $offset
27968         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27969
27970         # start at the first component but beyond end of object size
27971         printf "Seeking hole from 1000000 ... "
27972         offset=$(lseek_test -l 1000000 $file)
27973         echo $offset
27974         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27975         printf "Seeking data from 1000000 ... "
27976         offset=$(lseek_test -d 1000000 $file)
27977         echo $offset
27978         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27979
27980         # start at second component stripe 2 (empty file)
27981         printf "Seeking hole from 1500000 ... "
27982         offset=$(lseek_test -l 1500000 $file)
27983         echo $offset
27984         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27985         printf "Seeking data from 1500000 ... "
27986         offset=$(lseek_test -d 1500000 $file)
27987         echo $offset
27988         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27989
27990         # start at second component stripe 1 (all data)
27991         printf "Seeking hole from 3000000 ... "
27992         offset=$(lseek_test -l 3000000 $file)
27993         echo $offset
27994         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27995         printf "Seeking data from 3000000 ... "
27996         offset=$(lseek_test -d 3000000 $file)
27997         echo $offset
27998         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27999
28000         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28001                 error "2nd dd fails"
28002         echo "Add data block at 640K...1280K"
28003
28004         # start at before new data block, in hole
28005         printf "Seeking hole from 600000 ... "
28006         offset=$(lseek_test -l 600000 $file)
28007         echo $offset
28008         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28009         printf "Seeking data from 600000 ... "
28010         offset=$(lseek_test -d 600000 $file)
28011         echo $offset
28012         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28013
28014         # start at the first component new data block
28015         printf "Seeking hole from 1000000 ... "
28016         offset=$(lseek_test -l 1000000 $file)
28017         echo $offset
28018         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28019         printf "Seeking data from 1000000 ... "
28020         offset=$(lseek_test -d 1000000 $file)
28021         echo $offset
28022         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28023
28024         # start at second component stripe 2, new data
28025         printf "Seeking hole from 1200000 ... "
28026         offset=$(lseek_test -l 1200000 $file)
28027         echo $offset
28028         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28029         printf "Seeking data from 1200000 ... "
28030         offset=$(lseek_test -d 1200000 $file)
28031         echo $offset
28032         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28033
28034         # start beyond file end
28035         printf "Using offset > filesize ... "
28036         lseek_test -l 4000000 $file && error "lseek should fail"
28037         printf "Using offset > filesize ... "
28038         lseek_test -d 4000000 $file && error "lseek should fail"
28039
28040         printf "Done\n\n"
28041 }
28042
28043 test_430a() {
28044         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28045                 skip "MDT does not support SEEK_HOLE"
28046
28047         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28048                 skip "OST does not support SEEK_HOLE"
28049
28050         local file=$DIR/$tdir/$tfile
28051
28052         mkdir -p $DIR/$tdir
28053
28054         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28055         # OST stripe #1 will have continuous data at [1M, 3M)
28056         # OST stripe #2 is empty
28057         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28058         lseek_test_430 $file
28059         rm $file
28060         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28061         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28062         lseek_test_430 $file
28063         rm $file
28064         $LFS setstripe -c2 -S 512K $file
28065         echo "Two stripes, stripe size 512K"
28066         lseek_test_430 $file
28067         rm $file
28068         # FLR with stale mirror
28069         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28070                        -N -c2 -S 1M $file
28071         echo "Mirrored file:"
28072         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28073         echo "Plain 2 stripes 1M"
28074         lseek_test_430 $file
28075         rm $file
28076 }
28077 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28078
28079 test_430b() {
28080         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28081                 skip "OST does not support SEEK_HOLE"
28082
28083         local offset
28084         local file=$DIR/$tdir/$tfile
28085
28086         mkdir -p $DIR/$tdir
28087         # Empty layout lseek should fail
28088         $MCREATE $file
28089         # seek from 0
28090         printf "Seeking hole from 0 ... "
28091         lseek_test -l 0 $file && error "lseek should fail"
28092         printf "Seeking data from 0 ... "
28093         lseek_test -d 0 $file && error "lseek should fail"
28094         rm $file
28095
28096         # 1M-hole file
28097         $LFS setstripe -E 1M -c2 -E eof $file
28098         $TRUNCATE $file 1048576
28099         printf "Seeking hole from 1000000 ... "
28100         offset=$(lseek_test -l 1000000 $file)
28101         echo $offset
28102         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28103         printf "Seeking data from 1000000 ... "
28104         lseek_test -d 1000000 $file && error "lseek should fail"
28105         rm $file
28106
28107         # full component followed by non-inited one
28108         $LFS setstripe -E 1M -c2 -E eof $file
28109         dd if=/dev/urandom of=$file bs=1M count=1
28110         printf "Seeking hole from 1000000 ... "
28111         offset=$(lseek_test -l 1000000 $file)
28112         echo $offset
28113         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28114         printf "Seeking hole from 1048576 ... "
28115         lseek_test -l 1048576 $file && error "lseek should fail"
28116         # init second component and truncate back
28117         echo "123" >> $file
28118         $TRUNCATE $file 1048576
28119         printf "Seeking hole from 1000000 ... "
28120         offset=$(lseek_test -l 1000000 $file)
28121         echo $offset
28122         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28123         printf "Seeking hole from 1048576 ... "
28124         lseek_test -l 1048576 $file && error "lseek should fail"
28125         # boundary checks for big values
28126         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28127         offset=$(lseek_test -d 0 $file.10g)
28128         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28129         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28130         offset=$(lseek_test -d 0 $file.100g)
28131         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28132         return 0
28133 }
28134 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28135
28136 test_430c() {
28137         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28138                 skip "OST does not support SEEK_HOLE"
28139
28140         local file=$DIR/$tdir/$tfile
28141         local start
28142
28143         mkdir -p $DIR/$tdir
28144         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28145
28146         # cp version 8.33+ prefers lseek over fiemap
28147         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28148                 start=$SECONDS
28149                 time cp $file /dev/null
28150                 (( SECONDS - start < 5 )) ||
28151                         error "cp: too long runtime $((SECONDS - start))"
28152
28153         fi
28154         # tar version 1.29+ supports SEEK_HOLE/DATA
28155         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28156                 start=$SECONDS
28157                 time tar cS $file - | cat > /dev/null
28158                 (( SECONDS - start < 5 )) ||
28159                         error "tar: too long runtime $((SECONDS - start))"
28160         fi
28161 }
28162 run_test 430c "lseek: external tools check"
28163
28164 test_431() { # LU-14187
28165         local file=$DIR/$tdir/$tfile
28166
28167         mkdir -p $DIR/$tdir
28168         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28169         dd if=/dev/urandom of=$file bs=4k count=1
28170         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28171         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28172         #define OBD_FAIL_OST_RESTART_IO 0x251
28173         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28174         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28175         cp $file $file.0
28176         cancel_lru_locks
28177         sync_all_data
28178         echo 3 > /proc/sys/vm/drop_caches
28179         diff  $file $file.0 || error "data diff"
28180 }
28181 run_test 431 "Restart transaction for IO"
28182
28183 cleanup_test_432() {
28184         do_facet mgs $LCTL nodemap_activate 0
28185         wait_nm_sync active
28186 }
28187
28188 test_432() {
28189         local tmpdir=$TMP/dir432
28190
28191         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28192                 skip "Need MDS version at least 2.14.52"
28193
28194         stack_trap cleanup_test_432 EXIT
28195         mkdir $DIR/$tdir
28196         mkdir $tmpdir
28197
28198         do_facet mgs $LCTL nodemap_activate 1
28199         wait_nm_sync active
28200         do_facet mgs $LCTL nodemap_modify --name default \
28201                 --property admin --value 1
28202         do_facet mgs $LCTL nodemap_modify --name default \
28203                 --property trusted --value 1
28204         cancel_lru_locks mdc
28205         wait_nm_sync default admin_nodemap
28206         wait_nm_sync default trusted_nodemap
28207
28208         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28209                grep -ci "Operation not permitted") -ne 0 ]; then
28210                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28211         fi
28212 }
28213 run_test 432 "mv dir from outside Lustre"
28214
28215 test_433() {
28216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28217
28218         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28219                 skip "inode cache not supported"
28220
28221         $LCTL set_param llite.*.inode_cache=0
28222         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28223
28224         local count=256
28225         local before
28226         local after
28227
28228         cancel_lru_locks mdc
28229         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28230         createmany -m $DIR/$tdir/f $count
28231         createmany -d $DIR/$tdir/d $count
28232         ls -l $DIR/$tdir > /dev/null
28233         stack_trap "rm -rf $DIR/$tdir"
28234
28235         before=$(num_objects)
28236         cancel_lru_locks mdc
28237         after=$(num_objects)
28238
28239         # sometimes even @before is less than 2 * count
28240         while (( before - after < count )); do
28241                 sleep 1
28242                 after=$(num_objects)
28243                 wait=$((wait + 1))
28244                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28245                 if (( wait > 60 )); then
28246                         error "inode slab grew from $before to $after"
28247                 fi
28248         done
28249
28250         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28251 }
28252 run_test 433 "ldlm lock cancel releases dentries and inodes"
28253
28254 test_434() {
28255         local file
28256         local getxattr_count
28257         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28258         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28259
28260         [[ $(getenforce) == "Disabled" ]] ||
28261                 skip "lsm selinux module have to be disabled for this test"
28262
28263         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28264                 error "fail to create $DIR/$tdir/ on MDT0000"
28265
28266         touch $DIR/$tdir/$tfile-{001..100}
28267
28268         # disable the xattr cache
28269         save_lustre_params client "llite.*.xattr_cache" > $p
28270         lctl set_param llite.*.xattr_cache=0
28271         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28272
28273         # clear clients mdc stats
28274         clear_stats $mdc_stat_param ||
28275                 error "fail to clear stats on mdc MDT0000"
28276
28277         for file in $DIR/$tdir/$tfile-{001..100}; do
28278                 getfattr -n security.selinux $file |&
28279                         grep -q "Operation not supported" ||
28280                         error "getxattr on security.selinux should return EOPNOTSUPP"
28281         done
28282
28283         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28284         (( getxattr_count < 100 )) ||
28285                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28286 }
28287 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28288
28289 test_440() {
28290         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28291                 source $LUSTRE/scripts/bash-completion/lustre
28292         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28293                 source /usr/share/bash-completion/completions/lustre
28294         else
28295                 skip "bash completion scripts not found"
28296         fi
28297
28298         local lctl_completions
28299         local lfs_completions
28300
28301         lctl_completions=$(_lustre_cmds lctl)
28302         if [[ ! $lctl_completions =~ "get_param" ]]; then
28303                 error "lctl bash completion failed"
28304         fi
28305
28306         lfs_completions=$(_lustre_cmds lfs)
28307         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28308                 error "lfs bash completion failed"
28309         fi
28310 }
28311 run_test 440 "bash completion for lfs, lctl"
28312
28313 prep_801() {
28314         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28315         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28316                 skip "Need server version at least 2.9.55"
28317
28318         start_full_debug_logging
28319 }
28320
28321 post_801() {
28322         stop_full_debug_logging
28323 }
28324
28325 barrier_stat() {
28326         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28327                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28328                            awk '/The barrier for/ { print $7 }')
28329                 echo $st
28330         else
28331                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28332                 echo \'$st\'
28333         fi
28334 }
28335
28336 barrier_expired() {
28337         local expired
28338
28339         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28340                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28341                           awk '/will be expired/ { print $7 }')
28342         else
28343                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28344         fi
28345
28346         echo $expired
28347 }
28348
28349 test_801a() {
28350         prep_801
28351
28352         echo "Start barrier_freeze at: $(date)"
28353         #define OBD_FAIL_BARRIER_DELAY          0x2202
28354         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28355         # Do not reduce barrier time - See LU-11873
28356         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28357
28358         sleep 2
28359         local b_status=$(barrier_stat)
28360         echo "Got barrier status at: $(date)"
28361         [ "$b_status" = "'freezing_p1'" ] ||
28362                 error "(1) unexpected barrier status $b_status"
28363
28364         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28365         wait
28366         b_status=$(barrier_stat)
28367         [ "$b_status" = "'frozen'" ] ||
28368                 error "(2) unexpected barrier status $b_status"
28369
28370         local expired=$(barrier_expired)
28371         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28372         sleep $((expired + 3))
28373
28374         b_status=$(barrier_stat)
28375         [ "$b_status" = "'expired'" ] ||
28376                 error "(3) unexpected barrier status $b_status"
28377
28378         # Do not reduce barrier time - See LU-11873
28379         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28380                 error "(4) fail to freeze barrier"
28381
28382         b_status=$(barrier_stat)
28383         [ "$b_status" = "'frozen'" ] ||
28384                 error "(5) unexpected barrier status $b_status"
28385
28386         echo "Start barrier_thaw at: $(date)"
28387         #define OBD_FAIL_BARRIER_DELAY          0x2202
28388         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28389         do_facet mgs $LCTL barrier_thaw $FSNAME &
28390
28391         sleep 2
28392         b_status=$(barrier_stat)
28393         echo "Got barrier status at: $(date)"
28394         [ "$b_status" = "'thawing'" ] ||
28395                 error "(6) unexpected barrier status $b_status"
28396
28397         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28398         wait
28399         b_status=$(barrier_stat)
28400         [ "$b_status" = "'thawed'" ] ||
28401                 error "(7) unexpected barrier status $b_status"
28402
28403         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28404         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28405         do_facet mgs $LCTL barrier_freeze $FSNAME
28406
28407         b_status=$(barrier_stat)
28408         [ "$b_status" = "'failed'" ] ||
28409                 error "(8) unexpected barrier status $b_status"
28410
28411         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28412         do_facet mgs $LCTL barrier_thaw $FSNAME
28413
28414         post_801
28415 }
28416 run_test 801a "write barrier user interfaces and stat machine"
28417
28418 test_801b() {
28419         prep_801
28420
28421         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28422         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28423         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28424         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28425         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28426
28427         cancel_lru_locks mdc
28428
28429         # 180 seconds should be long enough
28430         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28431
28432         local b_status=$(barrier_stat)
28433         [ "$b_status" = "'frozen'" ] ||
28434                 error "(6) unexpected barrier status $b_status"
28435
28436         mkdir $DIR/$tdir/d0/d10 &
28437         mkdir_pid=$!
28438
28439         touch $DIR/$tdir/d1/f13 &
28440         touch_pid=$!
28441
28442         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28443         ln_pid=$!
28444
28445         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28446         mv_pid=$!
28447
28448         rm -f $DIR/$tdir/d4/f12 &
28449         rm_pid=$!
28450
28451         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28452
28453         # To guarantee taht the 'stat' is not blocked
28454         b_status=$(barrier_stat)
28455         [ "$b_status" = "'frozen'" ] ||
28456                 error "(8) unexpected barrier status $b_status"
28457
28458         # let above commands to run at background
28459         sleep 5
28460
28461         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28462         ps -p $touch_pid || error "(10) touch should be blocked"
28463         ps -p $ln_pid || error "(11) link should be blocked"
28464         ps -p $mv_pid || error "(12) rename should be blocked"
28465         ps -p $rm_pid || error "(13) unlink should be blocked"
28466
28467         b_status=$(barrier_stat)
28468         [ "$b_status" = "'frozen'" ] ||
28469                 error "(14) unexpected barrier status $b_status"
28470
28471         do_facet mgs $LCTL barrier_thaw $FSNAME
28472         b_status=$(barrier_stat)
28473         [ "$b_status" = "'thawed'" ] ||
28474                 error "(15) unexpected barrier status $b_status"
28475
28476         wait $mkdir_pid || error "(16) mkdir should succeed"
28477         wait $touch_pid || error "(17) touch should succeed"
28478         wait $ln_pid || error "(18) link should succeed"
28479         wait $mv_pid || error "(19) rename should succeed"
28480         wait $rm_pid || error "(20) unlink should succeed"
28481
28482         post_801
28483 }
28484 run_test 801b "modification will be blocked by write barrier"
28485
28486 test_801c() {
28487         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28488
28489         prep_801
28490
28491         stop mds2 || error "(1) Fail to stop mds2"
28492
28493         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28494
28495         local b_status=$(barrier_stat)
28496         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28497                 do_facet mgs $LCTL barrier_thaw $FSNAME
28498                 error "(2) unexpected barrier status $b_status"
28499         }
28500
28501         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28502                 error "(3) Fail to rescan barrier bitmap"
28503
28504         # Do not reduce barrier time - See LU-11873
28505         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28506
28507         b_status=$(barrier_stat)
28508         [ "$b_status" = "'frozen'" ] ||
28509                 error "(4) unexpected barrier status $b_status"
28510
28511         do_facet mgs $LCTL barrier_thaw $FSNAME
28512         b_status=$(barrier_stat)
28513         [ "$b_status" = "'thawed'" ] ||
28514                 error "(5) unexpected barrier status $b_status"
28515
28516         local devname=$(mdsdevname 2)
28517
28518         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28519
28520         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28521                 error "(7) Fail to rescan barrier bitmap"
28522
28523         post_801
28524 }
28525 run_test 801c "rescan barrier bitmap"
28526
28527 test_802b() {
28528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28529         remote_mds_nodsh && skip "remote MDS with nodsh"
28530
28531         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28532                 skip "readonly option not available"
28533
28534         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28535
28536         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28537                 error "(2) Fail to copy"
28538
28539         # write back all cached data before setting MDT to readonly
28540         cancel_lru_locks
28541         sync_all_data
28542
28543         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28544         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28545
28546         echo "Modify should be refused"
28547         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28548
28549         echo "Read should be allowed"
28550         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28551                 error "(7) Read should succeed under ro mode"
28552
28553         # disable readonly
28554         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28555 }
28556 run_test 802b "be able to set MDTs to readonly"
28557
28558 test_803a() {
28559         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28560         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28561                 skip "MDS needs to be newer than 2.10.54"
28562
28563         mkdir_on_mdt0 $DIR/$tdir
28564         # Create some objects on all MDTs to trigger related logs objects
28565         for idx in $(seq $MDSCOUNT); do
28566                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28567                         $DIR/$tdir/dir${idx} ||
28568                         error "Fail to create $DIR/$tdir/dir${idx}"
28569         done
28570
28571         wait_delete_completed # ensure old test cleanups are finished
28572         sleep 3
28573         echo "before create:"
28574         $LFS df -i $MOUNT
28575         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28576
28577         for i in {1..10}; do
28578                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28579                         error "Fail to create $DIR/$tdir/foo$i"
28580         done
28581
28582         # sync ZFS-on-MDS to refresh statfs data
28583         wait_zfs_commit mds1
28584         sleep 3
28585         echo "after create:"
28586         $LFS df -i $MOUNT
28587         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28588
28589         # allow for an llog to be cleaned up during the test
28590         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28591                 error "before ($before_used) + 10 > after ($after_used)"
28592
28593         for i in {1..10}; do
28594                 rm -rf $DIR/$tdir/foo$i ||
28595                         error "Fail to remove $DIR/$tdir/foo$i"
28596         done
28597
28598         # sync ZFS-on-MDS to refresh statfs data
28599         wait_zfs_commit mds1
28600         wait_delete_completed
28601         sleep 3 # avoid MDT return cached statfs
28602         echo "after unlink:"
28603         $LFS df -i $MOUNT
28604         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28605
28606         # allow for an llog to be created during the test
28607         [ $after_used -le $((before_used + 1)) ] ||
28608                 error "after ($after_used) > before ($before_used) + 1"
28609 }
28610 run_test 803a "verify agent object for remote object"
28611
28612 test_803b() {
28613         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28614         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28615                 skip "MDS needs to be newer than 2.13.56"
28616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28617
28618         for i in $(seq 0 $((MDSCOUNT - 1))); do
28619                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28620         done
28621
28622         local before=0
28623         local after=0
28624
28625         local tmp
28626
28627         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28628         for i in $(seq 0 $((MDSCOUNT - 1))); do
28629                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28630                         awk '/getattr/ { print $2 }')
28631                 before=$((before + tmp))
28632         done
28633         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28634         for i in $(seq 0 $((MDSCOUNT - 1))); do
28635                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28636                         awk '/getattr/ { print $2 }')
28637                 after=$((after + tmp))
28638         done
28639
28640         [ $before -eq $after ] || error "getattr count $before != $after"
28641 }
28642 run_test 803b "remote object can getattr from cache"
28643
28644 test_804() {
28645         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28646         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28647                 skip "MDS needs to be newer than 2.10.54"
28648         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28649
28650         mkdir -p $DIR/$tdir
28651         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28652                 error "Fail to create $DIR/$tdir/dir0"
28653
28654         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28655         local dev=$(mdsdevname 2)
28656
28657         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28658                 grep ${fid} || error "NOT found agent entry for dir0"
28659
28660         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28661                 error "Fail to create $DIR/$tdir/dir1"
28662
28663         touch $DIR/$tdir/dir1/foo0 ||
28664                 error "Fail to create $DIR/$tdir/dir1/foo0"
28665         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28666         local rc=0
28667
28668         for idx in $(seq $MDSCOUNT); do
28669                 dev=$(mdsdevname $idx)
28670                 do_facet mds${idx} \
28671                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28672                         grep ${fid} && rc=$idx
28673         done
28674
28675         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28676                 error "Fail to rename foo0 to foo1"
28677         if [ $rc -eq 0 ]; then
28678                 for idx in $(seq $MDSCOUNT); do
28679                         dev=$(mdsdevname $idx)
28680                         do_facet mds${idx} \
28681                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28682                         grep ${fid} && rc=$idx
28683                 done
28684         fi
28685
28686         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28687                 error "Fail to rename foo1 to foo2"
28688         if [ $rc -eq 0 ]; then
28689                 for idx in $(seq $MDSCOUNT); do
28690                         dev=$(mdsdevname $idx)
28691                         do_facet mds${idx} \
28692                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28693                         grep ${fid} && rc=$idx
28694                 done
28695         fi
28696
28697         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28698
28699         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28700                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28701         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28702                 error "Fail to rename foo2 to foo0"
28703         unlink $DIR/$tdir/dir1/foo0 ||
28704                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28705         rm -rf $DIR/$tdir/dir0 ||
28706                 error "Fail to rm $DIR/$tdir/dir0"
28707
28708         for idx in $(seq $MDSCOUNT); do
28709                 rc=0
28710
28711                 stop mds${idx}
28712                 dev=$(mdsdevname $idx)
28713                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28714                         rc=$?
28715                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28716                         error "mount mds$idx failed"
28717                 df $MOUNT > /dev/null 2>&1
28718
28719                 # e2fsck should not return error
28720                 [ $rc -eq 0 ] ||
28721                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28722         done
28723 }
28724 run_test 804 "verify agent entry for remote entry"
28725
28726 cleanup_805() {
28727         do_facet $SINGLEMDS zfs set quota=$old $fsset
28728         unlinkmany $DIR/$tdir/f- 1000000
28729         trap 0
28730 }
28731
28732 test_805() {
28733         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28734         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28735         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28736                 skip "netfree not implemented before 0.7"
28737         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28738                 skip "Need MDS version at least 2.10.57"
28739
28740         local fsset
28741         local freekb
28742         local usedkb
28743         local old
28744         local quota
28745         local pref="osd-zfs.$FSNAME-MDT0000."
28746
28747         # limit available space on MDS dataset to meet nospace issue
28748         # quickly. then ZFS 0.7.2 can use reserved space if asked
28749         # properly (using netfree flag in osd_declare_destroy()
28750         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28751         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28752                 gawk '{print $3}')
28753         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28754         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28755         let "usedkb=usedkb-freekb"
28756         let "freekb=freekb/2"
28757         if let "freekb > 5000"; then
28758                 let "freekb=5000"
28759         fi
28760         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28761         trap cleanup_805 EXIT
28762         mkdir_on_mdt0 $DIR/$tdir
28763         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28764                 error "Can't set PFL layout"
28765         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28766         rm -rf $DIR/$tdir || error "not able to remove"
28767         do_facet $SINGLEMDS zfs set quota=$old $fsset
28768         trap 0
28769 }
28770 run_test 805 "ZFS can remove from full fs"
28771
28772 # Size-on-MDS test
28773 check_lsom_data()
28774 {
28775         local file=$1
28776         local expect=$(stat -c %s $file)
28777
28778         check_lsom_size $1 $expect
28779
28780         local blocks=$($LFS getsom -b $file)
28781         expect=$(stat -c %b $file)
28782         [[ $blocks == $expect ]] ||
28783                 error "$file expected blocks: $expect, got: $blocks"
28784 }
28785
28786 check_lsom_size()
28787 {
28788         local size
28789         local expect=$2
28790
28791         cancel_lru_locks mdc
28792
28793         size=$($LFS getsom -s $1)
28794         [[ $size == $expect ]] ||
28795                 error "$file expected size: $expect, got: $size"
28796 }
28797
28798 test_806() {
28799         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28800                 skip "Need MDS version at least 2.11.52"
28801
28802         local bs=1048576
28803
28804         touch $DIR/$tfile || error "touch $tfile failed"
28805
28806         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28807         save_lustre_params client "llite.*.xattr_cache" > $save
28808         lctl set_param llite.*.xattr_cache=0
28809         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28810
28811         # single-threaded write
28812         echo "Test SOM for single-threaded write"
28813         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28814                 error "write $tfile failed"
28815         check_lsom_size $DIR/$tfile $bs
28816
28817         local num=32
28818         local size=$(($num * $bs))
28819         local offset=0
28820         local i
28821
28822         echo "Test SOM for single client multi-threaded($num) write"
28823         $TRUNCATE $DIR/$tfile 0
28824         for ((i = 0; i < $num; i++)); do
28825                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28826                 local pids[$i]=$!
28827                 offset=$((offset + $bs))
28828         done
28829         for (( i=0; i < $num; i++ )); do
28830                 wait ${pids[$i]}
28831         done
28832         check_lsom_size $DIR/$tfile $size
28833
28834         $TRUNCATE $DIR/$tfile 0
28835         for ((i = 0; i < $num; i++)); do
28836                 offset=$((offset - $bs))
28837                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28838                 local pids[$i]=$!
28839         done
28840         for (( i=0; i < $num; i++ )); do
28841                 wait ${pids[$i]}
28842         done
28843         check_lsom_size $DIR/$tfile $size
28844
28845         # multi-client writes
28846         num=$(get_node_count ${CLIENTS//,/ })
28847         size=$(($num * $bs))
28848         offset=0
28849         i=0
28850
28851         echo "Test SOM for multi-client ($num) writes"
28852         $TRUNCATE $DIR/$tfile 0
28853         for client in ${CLIENTS//,/ }; do
28854                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28855                 local pids[$i]=$!
28856                 i=$((i + 1))
28857                 offset=$((offset + $bs))
28858         done
28859         for (( i=0; i < $num; i++ )); do
28860                 wait ${pids[$i]}
28861         done
28862         check_lsom_size $DIR/$tfile $offset
28863
28864         i=0
28865         $TRUNCATE $DIR/$tfile 0
28866         for client in ${CLIENTS//,/ }; do
28867                 offset=$((offset - $bs))
28868                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28869                 local pids[$i]=$!
28870                 i=$((i + 1))
28871         done
28872         for (( i=0; i < $num; i++ )); do
28873                 wait ${pids[$i]}
28874         done
28875         check_lsom_size $DIR/$tfile $size
28876
28877         # verify truncate
28878         echo "Test SOM for truncate"
28879         $TRUNCATE $DIR/$tfile 1048576
28880         check_lsom_size $DIR/$tfile 1048576
28881         $TRUNCATE $DIR/$tfile 1234
28882         check_lsom_size $DIR/$tfile 1234
28883
28884         # verify SOM blocks count
28885         echo "Verify SOM block count"
28886         $TRUNCATE $DIR/$tfile 0
28887         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28888                 error "failed to write file $tfile"
28889         check_lsom_data $DIR/$tfile
28890 }
28891 run_test 806 "Verify Lazy Size on MDS"
28892
28893 test_807() {
28894         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28895         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28896                 skip "Need MDS version at least 2.11.52"
28897
28898         # Registration step
28899         changelog_register || error "changelog_register failed"
28900         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28901         changelog_users $SINGLEMDS | grep -q $cl_user ||
28902                 error "User $cl_user not found in changelog_users"
28903
28904         rm -rf $DIR/$tdir || error "rm $tdir failed"
28905         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28906         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28907         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28908         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28909                 error "truncate $tdir/trunc failed"
28910
28911         local bs=1048576
28912         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28913                 error "write $tfile failed"
28914
28915         # multi-client wirtes
28916         local num=$(get_node_count ${CLIENTS//,/ })
28917         local offset=0
28918         local i=0
28919
28920         echo "Test SOM for multi-client ($num) writes"
28921         touch $DIR/$tfile || error "touch $tfile failed"
28922         $TRUNCATE $DIR/$tfile 0
28923         for client in ${CLIENTS//,/ }; do
28924                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28925                 local pids[$i]=$!
28926                 i=$((i + 1))
28927                 offset=$((offset + $bs))
28928         done
28929         for (( i=0; i < $num; i++ )); do
28930                 wait ${pids[$i]}
28931         done
28932
28933         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28934         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28935         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28936         check_lsom_data $DIR/$tdir/trunc
28937         check_lsom_data $DIR/$tdir/single_dd
28938         check_lsom_data $DIR/$tfile
28939
28940         rm -rf $DIR/$tdir
28941         # Deregistration step
28942         changelog_deregister || error "changelog_deregister failed"
28943 }
28944 run_test 807 "verify LSOM syncing tool"
28945
28946 check_som_nologged()
28947 {
28948         local lines=$($LFS changelog $FSNAME-MDT0000 |
28949                 grep 'x=trusted.som' | wc -l)
28950         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28951 }
28952
28953 test_808() {
28954         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28955                 skip "Need MDS version at least 2.11.55"
28956
28957         # Registration step
28958         changelog_register || error "changelog_register failed"
28959
28960         touch $DIR/$tfile || error "touch $tfile failed"
28961         check_som_nologged
28962
28963         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28964                 error "write $tfile failed"
28965         check_som_nologged
28966
28967         $TRUNCATE $DIR/$tfile 1234
28968         check_som_nologged
28969
28970         $TRUNCATE $DIR/$tfile 1048576
28971         check_som_nologged
28972
28973         # Deregistration step
28974         changelog_deregister || error "changelog_deregister failed"
28975 }
28976 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28977
28978 check_som_nodata()
28979 {
28980         $LFS getsom $1
28981         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28982 }
28983
28984 test_809() {
28985         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28986                 skip "Need MDS version at least 2.11.56"
28987
28988         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28989                 error "failed to create DoM-only file $DIR/$tfile"
28990         touch $DIR/$tfile || error "touch $tfile failed"
28991         check_som_nodata $DIR/$tfile
28992
28993         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28994                 error "write $tfile failed"
28995         check_som_nodata $DIR/$tfile
28996
28997         $TRUNCATE $DIR/$tfile 1234
28998         check_som_nodata $DIR/$tfile
28999
29000         $TRUNCATE $DIR/$tfile 4097
29001         check_som_nodata $DIR/$file
29002 }
29003 run_test 809 "Verify no SOM xattr store for DoM-only files"
29004
29005 test_810() {
29006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29007         $GSS && skip_env "could not run with gss"
29008         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29009                 skip "OST < 2.12.58 doesn't align checksum"
29010
29011         set_checksums 1
29012         stack_trap "set_checksums $ORIG_CSUM" EXIT
29013         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29014
29015         local csum
29016         local before
29017         local after
29018         for csum in $CKSUM_TYPES; do
29019                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29020                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29021                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29022                         eval set -- $i
29023                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29024                         before=$(md5sum $DIR/$tfile)
29025                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29026                         after=$(md5sum $DIR/$tfile)
29027                         [ "$before" == "$after" ] ||
29028                                 error "$csum: $before != $after bs=$1 seek=$2"
29029                 done
29030         done
29031 }
29032 run_test 810 "partial page writes on ZFS (LU-11663)"
29033
29034 test_812a() {
29035         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29036                 skip "OST < 2.12.51 doesn't support this fail_loc"
29037
29038         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29039         # ensure ost1 is connected
29040         stat $DIR/$tfile >/dev/null || error "can't stat"
29041         wait_osc_import_state client ost1 FULL
29042         # no locks, no reqs to let the connection idle
29043         cancel_lru_locks osc
29044
29045         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29046 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29047         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29048         wait_osc_import_state client ost1 CONNECTING
29049         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29050
29051         stat $DIR/$tfile >/dev/null || error "can't stat file"
29052 }
29053 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29054
29055 test_812b() { # LU-12378
29056         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29057                 skip "OST < 2.12.51 doesn't support this fail_loc"
29058
29059         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29060         # ensure ost1 is connected
29061         stat $DIR/$tfile >/dev/null || error "can't stat"
29062         wait_osc_import_state client ost1 FULL
29063         # no locks, no reqs to let the connection idle
29064         cancel_lru_locks osc
29065
29066         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29067 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29068         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29069         wait_osc_import_state client ost1 CONNECTING
29070         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29071
29072         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29073         wait_osc_import_state client ost1 IDLE
29074 }
29075 run_test 812b "do not drop no resend request for idle connect"
29076
29077 test_812c() {
29078         local old
29079
29080         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29081
29082         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29083         $LFS getstripe $DIR/$tfile
29084         $LCTL set_param osc.*.idle_timeout=10
29085         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29086         # ensure ost1 is connected
29087         stat $DIR/$tfile >/dev/null || error "can't stat"
29088         wait_osc_import_state client ost1 FULL
29089         # no locks, no reqs to let the connection idle
29090         cancel_lru_locks osc
29091
29092 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29093         $LCTL set_param fail_loc=0x80000533
29094         sleep 15
29095         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29096 }
29097 run_test 812c "idle import vs lock enqueue race"
29098
29099 test_813() {
29100         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29101         [ -z "$file_heat_sav" ] && skip "no file heat support"
29102
29103         local readsample
29104         local writesample
29105         local readbyte
29106         local writebyte
29107         local readsample1
29108         local writesample1
29109         local readbyte1
29110         local writebyte1
29111
29112         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29113         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29114
29115         $LCTL set_param -n llite.*.file_heat=1
29116         echo "Turn on file heat"
29117         echo "Period second: $period_second, Decay percentage: $decay_pct"
29118
29119         echo "QQQQ" > $DIR/$tfile
29120         echo "QQQQ" > $DIR/$tfile
29121         echo "QQQQ" > $DIR/$tfile
29122         cat $DIR/$tfile > /dev/null
29123         cat $DIR/$tfile > /dev/null
29124         cat $DIR/$tfile > /dev/null
29125         cat $DIR/$tfile > /dev/null
29126
29127         local out=$($LFS heat_get $DIR/$tfile)
29128
29129         $LFS heat_get $DIR/$tfile
29130         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29131         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29132         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29133         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29134
29135         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29136         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29137         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29138         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29139
29140         sleep $((period_second + 3))
29141         echo "Sleep $((period_second + 3)) seconds..."
29142         # The recursion formula to calculate the heat of the file f is as
29143         # follow:
29144         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29145         # Where Hi is the heat value in the period between time points i*I and
29146         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29147         # to the weight of Ci.
29148         out=$($LFS heat_get $DIR/$tfile)
29149         $LFS heat_get $DIR/$tfile
29150         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29151         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29152         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29153         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29154
29155         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29156                 error "read sample ($readsample) is wrong"
29157         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29158                 error "write sample ($writesample) is wrong"
29159         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29160                 error "read bytes ($readbyte) is wrong"
29161         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29162                 error "write bytes ($writebyte) is wrong"
29163
29164         echo "QQQQ" > $DIR/$tfile
29165         echo "QQQQ" > $DIR/$tfile
29166         echo "QQQQ" > $DIR/$tfile
29167         cat $DIR/$tfile > /dev/null
29168         cat $DIR/$tfile > /dev/null
29169         cat $DIR/$tfile > /dev/null
29170         cat $DIR/$tfile > /dev/null
29171
29172         sleep $((period_second + 3))
29173         echo "Sleep $((period_second + 3)) seconds..."
29174
29175         out=$($LFS heat_get $DIR/$tfile)
29176         $LFS heat_get $DIR/$tfile
29177         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29178         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29179         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29180         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29181
29182         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29183                 4 * $decay_pct) / 100") -eq 1 ] ||
29184                 error "read sample ($readsample1) is wrong"
29185         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29186                 3 * $decay_pct) / 100") -eq 1 ] ||
29187                 error "write sample ($writesample1) is wrong"
29188         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29189                 20 * $decay_pct) / 100") -eq 1 ] ||
29190                 error "read bytes ($readbyte1) is wrong"
29191         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29192                 15 * $decay_pct) / 100") -eq 1 ] ||
29193                 error "write bytes ($writebyte1) is wrong"
29194
29195         echo "Turn off file heat for the file $DIR/$tfile"
29196         $LFS heat_set -o $DIR/$tfile
29197
29198         echo "QQQQ" > $DIR/$tfile
29199         echo "QQQQ" > $DIR/$tfile
29200         echo "QQQQ" > $DIR/$tfile
29201         cat $DIR/$tfile > /dev/null
29202         cat $DIR/$tfile > /dev/null
29203         cat $DIR/$tfile > /dev/null
29204         cat $DIR/$tfile > /dev/null
29205
29206         out=$($LFS heat_get $DIR/$tfile)
29207         $LFS heat_get $DIR/$tfile
29208         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29209         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29210         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29211         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29212
29213         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29214         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29215         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29216         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29217
29218         echo "Trun on file heat for the file $DIR/$tfile"
29219         $LFS heat_set -O $DIR/$tfile
29220
29221         echo "QQQQ" > $DIR/$tfile
29222         echo "QQQQ" > $DIR/$tfile
29223         echo "QQQQ" > $DIR/$tfile
29224         cat $DIR/$tfile > /dev/null
29225         cat $DIR/$tfile > /dev/null
29226         cat $DIR/$tfile > /dev/null
29227         cat $DIR/$tfile > /dev/null
29228
29229         out=$($LFS heat_get $DIR/$tfile)
29230         $LFS heat_get $DIR/$tfile
29231         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29232         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29233         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29234         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29235
29236         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29237         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29238         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29239         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29240
29241         $LFS heat_set -c $DIR/$tfile
29242         $LCTL set_param -n llite.*.file_heat=0
29243         echo "Turn off file heat support for the Lustre filesystem"
29244
29245         echo "QQQQ" > $DIR/$tfile
29246         echo "QQQQ" > $DIR/$tfile
29247         echo "QQQQ" > $DIR/$tfile
29248         cat $DIR/$tfile > /dev/null
29249         cat $DIR/$tfile > /dev/null
29250         cat $DIR/$tfile > /dev/null
29251         cat $DIR/$tfile > /dev/null
29252
29253         out=$($LFS heat_get $DIR/$tfile)
29254         $LFS heat_get $DIR/$tfile
29255         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29256         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29257         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29258         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29259
29260         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29261         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29262         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29263         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29264
29265         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29266         rm -f $DIR/$tfile
29267 }
29268 run_test 813 "File heat verfication"
29269
29270 test_814()
29271 {
29272         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29273         echo -n y >> $DIR/$tfile
29274         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29275         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29276 }
29277 run_test 814 "sparse cp works as expected (LU-12361)"
29278
29279 test_815()
29280 {
29281         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29282         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29283 }
29284 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29285
29286 test_816() {
29287         local ost1_imp=$(get_osc_import_name client ost1)
29288         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29289                          cut -d'.' -f2)
29290
29291         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29292         # ensure ost1 is connected
29293
29294         stat $DIR/$tfile >/dev/null || error "can't stat"
29295         wait_osc_import_state client ost1 FULL
29296         # no locks, no reqs to let the connection idle
29297         cancel_lru_locks osc
29298         lru_resize_disable osc
29299         local before
29300         local now
29301         before=$($LCTL get_param -n \
29302                  ldlm.namespaces.$imp_name.lru_size)
29303
29304         wait_osc_import_state client ost1 IDLE
29305         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29306         now=$($LCTL get_param -n \
29307               ldlm.namespaces.$imp_name.lru_size)
29308         [ $before == $now ] || error "lru_size changed $before != $now"
29309 }
29310 run_test 816 "do not reset lru_resize on idle reconnect"
29311
29312 cleanup_817() {
29313         umount $tmpdir
29314         exportfs -u localhost:$DIR/nfsexp
29315         rm -rf $DIR/nfsexp
29316 }
29317
29318 test_817() {
29319         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29320
29321         mkdir -p $DIR/nfsexp
29322         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29323                 error "failed to export nfs"
29324
29325         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29326         stack_trap cleanup_817 EXIT
29327
29328         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29329                 error "failed to mount nfs to $tmpdir"
29330
29331         cp /bin/true $tmpdir
29332         $DIR/nfsexp/true || error "failed to execute 'true' command"
29333 }
29334 run_test 817 "nfsd won't cache write lock for exec file"
29335
29336 test_818() {
29337         test_mkdir -i0 -c1 $DIR/$tdir
29338         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29339         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29340         stop $SINGLEMDS
29341
29342         # restore osp-syn threads
29343         stack_trap "fail $SINGLEMDS"
29344
29345         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29346         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29347         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29348                 error "start $SINGLEMDS failed"
29349         rm -rf $DIR/$tdir
29350
29351         local testid=$(echo $TESTNAME | tr '_' ' ')
29352
29353         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29354                 grep "run LFSCK" || error "run LFSCK is not suggested"
29355 }
29356 run_test 818 "unlink with failed llog"
29357
29358 test_819a() {
29359         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29360         cancel_lru_locks osc
29361         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29362         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29363         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29364         rm -f $TDIR/$tfile
29365 }
29366 run_test 819a "too big niobuf in read"
29367
29368 test_819b() {
29369         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29370         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29371         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29372         cancel_lru_locks osc
29373         sleep 1
29374         rm -f $TDIR/$tfile
29375 }
29376 run_test 819b "too big niobuf in write"
29377
29378
29379 function test_820_start_ost() {
29380         sleep 5
29381
29382         for num in $(seq $OSTCOUNT); do
29383                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29384         done
29385 }
29386
29387 test_820() {
29388         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29389
29390         mkdir $DIR/$tdir
29391         umount_client $MOUNT || error "umount failed"
29392         for num in $(seq $OSTCOUNT); do
29393                 stop ost$num
29394         done
29395
29396         # mount client with no active OSTs
29397         # so that the client can't initialize max LOV EA size
29398         # from OSC notifications
29399         mount_client $MOUNT || error "mount failed"
29400         # delay OST starting to keep this 0 max EA size for a while
29401         test_820_start_ost &
29402
29403         # create a directory on MDS2
29404         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29405                 error "Failed to create directory"
29406         # open intent should update default EA size
29407         # see mdc_update_max_ea_from_body()
29408         # notice this is the very first RPC to MDS2
29409         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29410         ret=$?
29411         echo $out
29412         # With SSK, this situation can lead to -EPERM being returned.
29413         # In that case, simply retry.
29414         if [ $ret -ne 0 ] && $SHARED_KEY; then
29415                 if echo "$out" | grep -q "not permitted"; then
29416                         cp /etc/services $DIR/$tdir/mds2
29417                         ret=$?
29418                 fi
29419         fi
29420         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29421 }
29422 run_test 820 "update max EA from open intent"
29423
29424 test_823() {
29425         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29426         local OST_MAX_PRECREATE=20000
29427
29428         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29429                 skip "Need MDS version at least 2.14.56"
29430
29431         save_lustre_params mds1 \
29432                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29433         do_facet $SINGLEMDS "$LCTL set_param -n \
29434                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29435         do_facet $SINGLEMDS "$LCTL set_param -n \
29436                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29437
29438         stack_trap "restore_lustre_params < $p; rm $p"
29439
29440         do_facet $SINGLEMDS "$LCTL set_param -n \
29441                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29442
29443         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29444                       osp.$FSNAME-OST0000*MDT0000.create_count")
29445         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29446                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29447         local expect_count=$(((($max/2)/256) * 256))
29448
29449         log "setting create_count to 100200:"
29450         log " -result- count: $count with max: $max, expecting: $expect_count"
29451
29452         [[ $count -eq expect_count ]] ||
29453                 error "Create count not set to max precreate."
29454 }
29455 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29456
29457 test_831() {
29458         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29459                 skip "Need MDS version 2.14.56"
29460
29461         local sync_changes=$(do_facet $SINGLEMDS \
29462                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29463
29464         [ "$sync_changes" -gt 100 ] &&
29465                 skip "Sync changes $sync_changes > 100 already"
29466
29467         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29468
29469         $LFS mkdir -i 0 $DIR/$tdir
29470         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29471
29472         save_lustre_params mds1 \
29473                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29474         save_lustre_params mds1 \
29475                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29476
29477         do_facet mds1 "$LCTL set_param -n \
29478                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29479                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29480         stack_trap "restore_lustre_params < $p" EXIT
29481
29482         createmany -o $DIR/$tdir/f- 1000
29483         unlinkmany $DIR/$tdir/f- 1000 &
29484         local UNLINK_PID=$!
29485
29486         while sleep 1; do
29487                 sync_changes=$(do_facet mds1 \
29488                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29489                 # the check in the code is racy, fail the test
29490                 # if the value above the limit by 10.
29491                 [ $sync_changes -gt 110 ] && {
29492                         kill -2 $UNLINK_PID
29493                         wait
29494                         error "osp changes throttling failed, $sync_changes>110"
29495                 }
29496                 kill -0 $UNLINK_PID 2> /dev/null || break
29497         done
29498         wait
29499 }
29500 run_test 831 "throttling unlink/setattr queuing on OSP"
29501
29502 test_832() {
29503         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29504         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29505                 skip "Need MDS version 2.15.52+"
29506         is_rmentry_supported || skip "rm_entry not supported"
29507
29508         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29509         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29510         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29511                 error "mkdir remote_dir failed"
29512         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29513                 error "mkdir striped_dir failed"
29514         touch $DIR/$tdir/file || error "touch file failed"
29515         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29516         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29517 }
29518 run_test 832 "lfs rm_entry"
29519
29520 #
29521 # tests that do cleanup/setup should be run at the end
29522 #
29523
29524 test_900() {
29525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29526         local ls
29527
29528         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29529         $LCTL set_param fail_loc=0x903
29530
29531         cancel_lru_locks MGC
29532
29533         FAIL_ON_ERROR=true cleanup
29534         FAIL_ON_ERROR=true setup
29535 }
29536 run_test 900 "umount should not race with any mgc requeue thread"
29537
29538 # LUS-6253/LU-11185
29539 test_901() {
29540         local old
29541         local count
29542         local oldc
29543         local newc
29544         local olds
29545         local news
29546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29547
29548         # some get_param have a bug to handle dot in param name
29549         cancel_lru_locks MGC
29550         old=$(mount -t lustre | wc -l)
29551         # 1 config+sptlrpc
29552         # 2 params
29553         # 3 nodemap
29554         # 4 IR
29555         old=$((old * 4))
29556         oldc=0
29557         count=0
29558         while [ $old -ne $oldc ]; do
29559                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29560                 sleep 1
29561                 ((count++))
29562                 if [ $count -ge $TIMEOUT ]; then
29563                         error "too large timeout"
29564                 fi
29565         done
29566         umount_client $MOUNT || error "umount failed"
29567         mount_client $MOUNT || error "mount failed"
29568         cancel_lru_locks MGC
29569         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29570
29571         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29572
29573         return 0
29574 }
29575 run_test 901 "don't leak a mgc lock on client umount"
29576
29577 # LU-13377
29578 test_902() {
29579         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29580                 skip "client does not have LU-13377 fix"
29581         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29582         $LCTL set_param fail_loc=0x1415
29583         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29584         cancel_lru_locks osc
29585         rm -f $DIR/$tfile
29586 }
29587 run_test 902 "test short write doesn't hang lustre"
29588
29589 # LU-14711
29590 test_903() {
29591         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29592         echo "blah" > $DIR/${tfile}-2
29593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29594         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29595         $LCTL set_param fail_loc=0x417 fail_val=20
29596
29597         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29598         sleep 1 # To start the destroy
29599         wait_destroy_complete 150 || error "Destroy taking too long"
29600         cat $DIR/$tfile > /dev/null || error "Evicted"
29601 }
29602 run_test 903 "Test long page discard does not cause evictions"
29603
29604 test_904() {
29605         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29606         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29607                 grep -q project || skip "skip project quota not supported"
29608
29609         local testfile="$DIR/$tdir/$tfile"
29610         local xattr="trusted.projid"
29611         local projid
29612         local mdts=$(comma_list $(mdts_nodes))
29613         local saved=$(do_facet mds1 $LCTL get_param -n \
29614                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29615
29616         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29617         stack_trap "do_nodes $mdts $LCTL set_param \
29618                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29619
29620         mkdir -p $DIR/$tdir
29621         touch $testfile
29622         #hide projid xattr on server
29623         $LFS project -p 1 $testfile ||
29624                 error "set $testfile project id failed"
29625         getfattr -m - $testfile | grep $xattr &&
29626                 error "do not show trusted.projid when disabled on server"
29627         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29628         #should be hidden when projid is 0
29629         $LFS project -p 0 $testfile ||
29630                 error "set $testfile project id failed"
29631         getfattr -m - $testfile | grep $xattr &&
29632                 error "do not show trusted.projid with project ID 0"
29633
29634         #still can getxattr explicitly
29635         projid=$(getfattr -n $xattr $testfile |
29636                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29637         [ $projid == "0" ] ||
29638                 error "projid expected 0 not $projid"
29639
29640         #set the projid via setxattr
29641         setfattr -n $xattr -v "1000" $testfile ||
29642                 error "setattr failed with $?"
29643         projid=($($LFS project $testfile))
29644         [ ${projid[0]} == "1000" ] ||
29645                 error "projid expected 1000 not $projid"
29646
29647         #check the new projid via getxattr
29648         $LFS project -p 1001 $testfile ||
29649                 error "set $testfile project id failed"
29650         getfattr -m - $testfile | grep $xattr ||
29651                 error "should show trusted.projid when project ID != 0"
29652         projid=$(getfattr -n $xattr $testfile |
29653                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29654         [ $projid == "1001" ] ||
29655                 error "projid expected 1001 not $projid"
29656
29657         #try to set invalid projid
29658         setfattr -n $xattr -v "4294967295" $testfile &&
29659                 error "set invalid projid should fail"
29660
29661         #remove the xattr means setting projid to 0
29662         setfattr -x $xattr $testfile ||
29663                 error "setfattr failed with $?"
29664         projid=($($LFS project $testfile))
29665         [ ${projid[0]} == "0" ] ||
29666                 error "projid expected 0 not $projid"
29667
29668         #should be hidden when parent has inherit flag and same projid
29669         $LFS project -srp 1002 $DIR/$tdir ||
29670                 error "set $tdir project id failed"
29671         getfattr -m - $testfile | grep $xattr &&
29672                 error "do not show trusted.projid with inherit flag"
29673
29674         #still can getxattr explicitly
29675         projid=$(getfattr -n $xattr $testfile |
29676                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29677         [ $projid == "1002" ] ||
29678                 error "projid expected 1002 not $projid"
29679 }
29680 run_test 904 "virtual project ID xattr"
29681
29682 # LU-8582
29683 test_905() {
29684         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29685                 skip "lustre < 2.8.54 does not support ladvise"
29686
29687         remote_ost_nodsh && skip "remote OST with nodsh"
29688         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29689
29690         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29691
29692         #define OBD_FAIL_OST_OPCODE 0x253
29693         # OST_LADVISE = 21
29694         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29695         $LFS ladvise -a willread $DIR/$tfile &&
29696                 error "unexpected success of ladvise with fault injection"
29697         $LFS ladvise -a willread $DIR/$tfile |&
29698                 grep -q "Operation not supported"
29699         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29700 }
29701 run_test 905 "bad or new opcode should not stuck client"
29702
29703 test_906() {
29704         grep -q io_uring_setup /proc/kallsyms ||
29705                 skip "Client OS does not support io_uring I/O engine"
29706         io_uring_probe || skip "kernel does not support io_uring fully"
29707         which fio || skip_env "no fio installed"
29708         fio --enghelp | grep -q io_uring ||
29709                 skip_env "fio does not support io_uring I/O engine"
29710
29711         local file=$DIR/$tfile
29712         local ioengine="io_uring"
29713         local numjobs=2
29714         local size=50M
29715
29716         fio --name=seqwrite --ioengine=$ioengine        \
29717                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29718                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29719                 error "fio seqwrite $file failed"
29720
29721         fio --name=seqread --ioengine=$ioengine \
29722                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29723                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29724                 error "fio seqread $file failed"
29725
29726         rm -f $file || error "rm -f $file failed"
29727 }
29728 run_test 906 "Simple test for io_uring I/O engine via fio"
29729
29730 complete $SECONDS
29731 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29732 check_and_cleanup_lustre
29733 if [ "$I_MOUNTED" != "yes" ]; then
29734         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29735 fi
29736 exit_status