Whamcloud - gitweb
Revert "LU-16046 ldlm: group lock fix"
[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-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46 always_except LU-16046 244b
47
48 if $SHARED_KEY; then
49         always_except LU-14181 64e 64f
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         always_except LU-11671 45
55 fi
56
57 # skip nfs tests on kernels >= 4.12.0 until they are fixed
58 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
59         always_except LU-12661 817
60 fi
61 # skip cgroup tests on RHEL8.1 kernels until they are fixed
62 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
63       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
64         always_except LU-13063 411
65 fi
66
67 #                                  5              12     8   12  15   (min)"
68 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
69
70 if [ "$mds1_FSTYPE" = "zfs" ]; then
71         #                                               13    (min)"
72         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
73 fi
74
75 if [ "$ost1_FSTYPE" = "zfs" ]; then
76         always_except LU-1941 130b 130c 130d 130e 130f 130g
77 fi
78
79 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
80
81 # Get the SLES distro version
82 #
83 # Returns a version string that should only be used in comparing
84 # strings returned by version_code()
85 sles_version_code()
86 {
87         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
88
89         # All SuSE Linux versions have one decimal. version_code expects two
90         local sles_version=$version.0
91         version_code $sles_version
92 }
93
94 # Check if we are running on Ubuntu or SLES so we can make decisions on
95 # what tests to run
96 if [ -r /etc/SuSE-release ]; then
97         sles_version=$(sles_version_code)
98         [ $sles_version -lt $(version_code 11.4.0) ] &&
99                 always_except LU-4341 170
100
101         [ $sles_version -lt $(version_code 12.0.0) ] &&
102                 always_except LU-3703 234
103 elif [ -r /etc/os-release ]; then
104         if grep -qi ubuntu /etc/os-release; then
105                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
106                                                 -e 's/^VERSION=//p' \
107                                                 /etc/os-release |
108                                                 awk '{ print $1 }'))
109
110                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
111                         always_except LU-10366 410
112                 fi
113         fi
114 fi
115
116 build_test_filter
117 FAIL_ON_ERROR=false
118
119 cleanup() {
120         echo -n "cln.."
121         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
122         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
123 }
124 setup() {
125         echo -n "mnt.."
126         load_modules
127         setupall || exit 10
128         echo "done"
129 }
130
131 check_swap_layouts_support()
132 {
133         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
134                 skip "Does not support layout lock."
135 }
136
137 check_swap_layout_no_dom()
138 {
139         local FOLDER=$1
140         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
141         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 if [ "${ONLY}" = "MOUNT" ] ; then
161         echo "Lustre is up, please go on"
162         exit
163 fi
164
165 echo "preparing for tests involving mounts"
166 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
167 touch $EXT2_DEV
168 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
169 echo # add a newline after mke2fs.
170
171 umask 077
172
173 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
174 lctl set_param debug=-1 2> /dev/null || true
175 test_0a() {
176         touch $DIR/$tfile
177         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
178         rm $DIR/$tfile
179         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
180 }
181 run_test 0a "touch; rm ====================="
182
183 test_0b() {
184         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
185         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
186 }
187 run_test 0b "chmod 0755 $DIR ============================="
188
189 test_0c() {
190         $LCTL get_param mdc.*.import | grep "state: FULL" ||
191                 error "import not FULL"
192         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
193                 error "bad target"
194 }
195 run_test 0c "check import proc"
196
197 test_0d() { # LU-3397
198         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
199                 skip "proc exports not supported before 2.10.57"
200
201         local mgs_exp="mgs.MGS.exports"
202         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
203         local exp_client_nid
204         local exp_client_version
205         local exp_val
206         local imp_val
207         local temp_imp=$DIR/$tfile.import
208         local temp_exp=$DIR/$tfile.export
209
210         # save mgc import file to $temp_imp
211         $LCTL get_param mgc.*.import | tee $temp_imp
212         # Check if client uuid is found in MGS export
213         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
214                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
215                         $client_uuid ] &&
216                         break;
217         done
218         # save mgs export file to $temp_exp
219         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
220
221         # Compare the value of field "connect_flags"
222         imp_val=$(grep "connect_flags" $temp_imp)
223         exp_val=$(grep "connect_flags" $temp_exp)
224         [ "$exp_val" == "$imp_val" ] ||
225                 error "export flags '$exp_val' != import flags '$imp_val'"
226
227         # Compare client versions.  Only compare top-3 fields for compatibility
228         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
229         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
230         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
231         [ "$exp_val" == "$imp_val" ] ||
232                 error "exp version '$exp_client_version'($exp_val) != " \
233                         "'$(lustre_build_version client)'($imp_val)"
234 }
235 run_test 0d "check export proc ============================="
236
237 test_0e() { # LU-13417
238         (( $MDSCOUNT > 1 )) ||
239                 skip "We need at least 2 MDTs for this test"
240
241         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
242                 skip "Need server version at least 2.14.51"
243
244         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
245         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
246
247         [ $default_lmv_count -eq 1 ] ||
248                 error "$MOUNT default stripe count $default_lmv_count"
249
250         [ $default_lmv_index -eq -1 ] ||
251                 error "$MOUNT default stripe index $default_lmv_index"
252
253         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
254         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
255
256         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
257         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
258
259         [ $mdt_index1 -eq $mdt_index2 ] &&
260                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
261
262         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
263 }
264 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
265
266 test_1() {
267         test_mkdir $DIR/$tdir
268         test_mkdir $DIR/$tdir/d2
269         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
270         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
271         rmdir $DIR/$tdir/d2
272         rmdir $DIR/$tdir
273         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
274 }
275 run_test 1 "mkdir; remkdir; rmdir"
276
277 test_2() {
278         test_mkdir $DIR/$tdir
279         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
280         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
281         rm -r $DIR/$tdir
282         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
283 }
284 run_test 2 "mkdir; touch; rmdir; check file"
285
286 test_3() {
287         test_mkdir $DIR/$tdir
288         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
289         touch $DIR/$tdir/$tfile
290         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
291         rm -r $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
293 }
294 run_test 3 "mkdir; touch; rmdir; check dir"
295
296 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
297 test_4() {
298         test_mkdir -i 1 $DIR/$tdir
299
300         touch $DIR/$tdir/$tfile ||
301                 error "Create file under remote directory failed"
302
303         rmdir $DIR/$tdir &&
304                 error "Expect error removing in-use dir $DIR/$tdir"
305
306         test -d $DIR/$tdir || error "Remote directory disappeared"
307
308         rm -rf $DIR/$tdir || error "remove remote dir error"
309 }
310 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
311
312 test_5() {
313         test_mkdir $DIR/$tdir
314         test_mkdir $DIR/$tdir/d2
315         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
316         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
317         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
318 }
319 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
320
321 test_6a() {
322         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
323         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
324         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
325                 error "$tfile does not have perm 0666 or UID $UID"
326         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
327         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
328                 error "$tfile should be 0666 and owned by UID $UID"
329 }
330 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
331
332 test_6c() {
333         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
334
335         touch $DIR/$tfile
336         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
337         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
338                 error "$tfile should be owned by UID $RUNAS_ID"
339         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
340         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
341                 error "$tfile should be owned by UID $RUNAS_ID"
342 }
343 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
344
345 test_6e() {
346         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
347
348         touch $DIR/$tfile
349         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
350         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
351                 error "$tfile should be owned by GID $UID"
352         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
353         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
354                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
355 }
356 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
357
358 test_6g() {
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         test_mkdir $DIR/$tdir
362         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
363         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
364         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
365         test_mkdir $DIR/$tdir/d/subdir
366         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
367                 error "$tdir/d/subdir should be GID $RUNAS_GID"
368         if [[ $MDSCOUNT -gt 1 ]]; then
369                 # check remote dir sgid inherite
370                 $LFS mkdir -i 0 $DIR/$tdir.local ||
371                         error "mkdir $tdir.local failed"
372                 chmod g+s $DIR/$tdir.local ||
373                         error "chmod $tdir.local failed"
374                 chgrp $RUNAS_GID $DIR/$tdir.local ||
375                         error "chgrp $tdir.local failed"
376                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
377                         error "mkdir $tdir.remote failed"
378                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
379                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
380                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
381                         error "$tdir.remote should be mode 02755"
382         fi
383 }
384 run_test 6g "verify new dir in sgid dir inherits group"
385
386 test_6h() { # bug 7331
387         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
388
389         touch $DIR/$tfile || error "touch failed"
390         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
391         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
392                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
393         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
394                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
395 }
396 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
397
398 test_7a() {
399         test_mkdir $DIR/$tdir
400         $MCREATE $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tdir/$tfile should be mode 0666"
404 }
405 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
406
407 test_7b() {
408         if [ ! -d $DIR/$tdir ]; then
409                 test_mkdir $DIR/$tdir
410         fi
411         $MCREATE $DIR/$tdir/$tfile
412         echo -n foo > $DIR/$tdir/$tfile
413         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
414         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
415 }
416 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
417
418 test_8() {
419         test_mkdir $DIR/$tdir
420         touch $DIR/$tdir/$tfile
421         chmod 0666 $DIR/$tdir/$tfile
422         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
423                 error "$tfile mode not 0666"
424 }
425 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
426
427 test_9() {
428         test_mkdir $DIR/$tdir
429         test_mkdir $DIR/$tdir/d2
430         test_mkdir $DIR/$tdir/d2/d3
431         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
432 }
433 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
434
435 test_10() {
436         test_mkdir $DIR/$tdir
437         test_mkdir $DIR/$tdir/d2
438         touch $DIR/$tdir/d2/$tfile
439         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
440                 error "$tdir/d2/$tfile not a file"
441 }
442 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
443
444 test_11() {
445         test_mkdir $DIR/$tdir
446         test_mkdir $DIR/$tdir/d2
447         chmod 0666 $DIR/$tdir/d2
448         chmod 0705 $DIR/$tdir/d2
449         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
450                 error "$tdir/d2 mode not 0705"
451 }
452 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
453
454 test_12() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         chmod 0666 $DIR/$tdir/$tfile
458         chmod 0654 $DIR/$tdir/$tfile
459         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
460                 error "$tdir/d2 mode not 0654"
461 }
462 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
463
464 test_13() {
465         test_mkdir $DIR/$tdir
466         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
467         >  $DIR/$tdir/$tfile
468         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
469                 error "$tdir/$tfile size not 0 after truncate"
470 }
471 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
472
473 test_14() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         rm $DIR/$tdir/$tfile
477         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
478 }
479 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
480
481 test_15() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
485         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
486                 error "$tdir/${tfile_2} not a file after rename"
487         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
488 }
489 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
490
491 test_16() {
492         test_mkdir $DIR/$tdir
493         touch $DIR/$tdir/$tfile
494         rm -rf $DIR/$tdir/$tfile
495         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
496 }
497 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
498
499 test_17a() {
500         test_mkdir $DIR/$tdir
501         touch $DIR/$tdir/$tfile
502         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
503         ls -l $DIR/$tdir
504         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
505                 error "$tdir/l-exist not a symlink"
506         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
507                 error "$tdir/l-exist not referencing a file"
508         rm -f $DIR/$tdir/l-exist
509         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
510 }
511 run_test 17a "symlinks: create, remove (real)"
512
513 test_17b() {
514         test_mkdir $DIR/$tdir
515         ln -s no-such-file $DIR/$tdir/l-dangle
516         ls -l $DIR/$tdir
517         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
518                 error "$tdir/l-dangle not referencing no-such-file"
519         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
520                 error "$tdir/l-dangle not referencing non-existent file"
521         rm -f $DIR/$tdir/l-dangle
522         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
523 }
524 run_test 17b "symlinks: create, remove (dangling)"
525
526 test_17c() { # bug 3440 - don't save failed open RPC for replay
527         test_mkdir $DIR/$tdir
528         ln -s foo $DIR/$tdir/$tfile
529         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
530 }
531 run_test 17c "symlinks: open dangling (should return error)"
532
533 test_17d() {
534         test_mkdir $DIR/$tdir
535         ln -s foo $DIR/$tdir/$tfile
536         touch $DIR/$tdir/$tfile || error "creating to new symlink"
537 }
538 run_test 17d "symlinks: create dangling"
539
540 test_17e() {
541         test_mkdir $DIR/$tdir
542         local foo=$DIR/$tdir/$tfile
543         ln -s $foo $foo || error "create symlink failed"
544         ls -l $foo || error "ls -l failed"
545         ls $foo && error "ls not failed" || true
546 }
547 run_test 17e "symlinks: create recursive symlink (should return error)"
548
549 test_17f() {
550         test_mkdir $DIR/$tdir
551         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
556         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
557         ls -l  $DIR/$tdir
558 }
559 run_test 17f "symlinks: long and very long symlink name"
560
561 # str_repeat(S, N) generate a string that is string S repeated N times
562 str_repeat() {
563         local s=$1
564         local n=$2
565         local ret=''
566         while [ $((n -= 1)) -ge 0 ]; do
567                 ret=$ret$s
568         done
569         echo $ret
570 }
571
572 # Long symlinks and LU-2241
573 test_17g() {
574         test_mkdir $DIR/$tdir
575         local TESTS="59 60 61 4094 4095"
576
577         # Fix for inode size boundary in 2.1.4
578         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
579                 TESTS="4094 4095"
580
581         # Patch not applied to 2.2 or 2.3 branches
582         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
583         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
584                 TESTS="4094 4095"
585
586         for i in $TESTS; do
587                 local SYMNAME=$(str_repeat 'x' $i)
588                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
589                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
590         done
591 }
592 run_test 17g "symlinks: really long symlink name and inode boundaries"
593
594 test_17h() { #bug 17378
595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
596         remote_mds_nodsh && skip "remote MDS with nodsh"
597
598         local mdt_idx
599
600         test_mkdir $DIR/$tdir
601         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
602         $LFS setstripe -c -1 $DIR/$tdir
603         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
604         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
605         touch $DIR/$tdir/$tfile || true
606 }
607 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
608
609 test_17i() { #bug 20018
610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
611         remote_mds_nodsh && skip "remote MDS with nodsh"
612
613         local foo=$DIR/$tdir/$tfile
614         local mdt_idx
615
616         test_mkdir -c1 $DIR/$tdir
617         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
618         ln -s $foo $foo || error "create symlink failed"
619 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
620         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
621         ls -l $foo && error "error not detected"
622         return 0
623 }
624 run_test 17i "don't panic on short symlink (should return error)"
625
626 test_17k() { #bug 22301
627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
628         [[ -z "$(which rsync 2>/dev/null)" ]] &&
629                 skip "no rsync command"
630         rsync --help | grep -q xattr ||
631                 skip_env "$(rsync --version | head -n1) does not support xattrs"
632         test_mkdir $DIR/$tdir
633         test_mkdir $DIR/$tdir.new
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
637                 error "rsync failed with xattrs enabled"
638 }
639 run_test 17k "symlinks: rsync with xattrs enabled"
640
641 test_17l() { # LU-279
642         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
643                 skip "no getfattr command"
644
645         test_mkdir $DIR/$tdir
646         touch $DIR/$tdir/$tfile
647         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
648         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
649                 # -h to not follow symlinks. -m '' to list all the xattrs.
650                 # grep to remove first line: '# file: $path'.
651                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
652                 do
653                         lgetxattr_size_check $path $xattr ||
654                                 error "lgetxattr_size_check $path $xattr failed"
655                 done
656         done
657 }
658 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
659
660 # LU-1540
661 test_17m() {
662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
663         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
664         remote_mds_nodsh && skip "remote MDS with nodsh"
665         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
666         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
667                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
668
669         local short_sym="0123456789"
670         local wdir=$DIR/$tdir
671         local i
672
673         test_mkdir $wdir
674         long_sym=$short_sym
675         # create a long symlink file
676         for ((i = 0; i < 4; ++i)); do
677                 long_sym=${long_sym}${long_sym}
678         done
679
680         echo "create 512 short and long symlink files under $wdir"
681         for ((i = 0; i < 256; ++i)); do
682                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
683                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
684         done
685
686         echo "erase them"
687         rm -f $wdir/*
688         sync
689         wait_delete_completed
690
691         echo "recreate the 512 symlink files with a shorter string"
692         for ((i = 0; i < 512; ++i)); do
693                 # rewrite the symlink file with a shorter string
694                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
695                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
696         done
697
698         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
699
700         echo "stop and checking mds${mds_index}:"
701         # e2fsck should not return error
702         stop mds${mds_index}
703         local devname=$(mdsdevname $mds_index)
704         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
705         rc=$?
706
707         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
708                 error "start mds${mds_index} failed"
709         df $MOUNT > /dev/null 2>&1
710         [ $rc -eq 0 ] ||
711                 error "e2fsck detected error for short/long symlink: rc=$rc"
712         rm -f $wdir/*
713 }
714 run_test 17m "run e2fsck against MDT which contains short/long symlink"
715
716 check_fs_consistency_17n() {
717         local mdt_index
718         local rc=0
719
720         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
721         # so it only check MDT1/MDT2 instead of all of MDTs.
722         for mdt_index in 1 2; do
723                 # e2fsck should not return error
724                 stop mds${mdt_index}
725                 local devname=$(mdsdevname $mdt_index)
726                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
727                         rc=$((rc + $?))
728
729                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
730                         error "mount mds$mdt_index failed"
731                 df $MOUNT > /dev/null 2>&1
732         done
733         return $rc
734 }
735
736 test_17n() {
737         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
739         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
740         remote_mds_nodsh && skip "remote MDS with nodsh"
741         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
742         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
743                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
744
745         local i
746
747         test_mkdir $DIR/$tdir
748         for ((i=0; i<10; i++)); do
749                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
750                         error "create remote dir error $i"
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753         done
754
755         check_fs_consistency_17n ||
756                 error "e2fsck report error after create files under remote dir"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n ||
764                 error "e2fsck report error after unlink files under remote dir"
765
766         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
767                 skip "lustre < 2.4.50 does not support migrate mv"
768
769         for ((i = 0; i < 10; i++)); do
770                 mkdir -p $DIR/$tdir/remote_dir_${i}
771                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
772                         error "create files under remote dir failed $i"
773                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
774                         error "migrate remote dir error $i"
775         done
776         check_fs_consistency_17n || error "e2fsck report error after migration"
777
778         for ((i = 0; i < 10; i++)); do
779                 rm -rf $DIR/$tdir/remote_dir_${i} ||
780                         error "destroy remote dir error $i"
781         done
782
783         check_fs_consistency_17n || error "e2fsck report error after unlink"
784 }
785 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
786
787 test_17o() {
788         remote_mds_nodsh && skip "remote MDS with nodsh"
789         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
790                 skip "Need MDS version at least 2.3.64"
791
792         local wdir=$DIR/${tdir}o
793         local mdt_index
794         local rc=0
795
796         test_mkdir $wdir
797         touch $wdir/$tfile
798         mdt_index=$($LFS getstripe -m $wdir/$tfile)
799         mdt_index=$((mdt_index + 1))
800
801         cancel_lru_locks mdc
802         #fail mds will wait the failover finish then set
803         #following fail_loc to avoid interfer the recovery process.
804         fail mds${mdt_index}
805
806         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
807         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
808         ls -l $wdir/$tfile && rc=1
809         do_facet mds${mdt_index} lctl set_param fail_loc=0
810         [[ $rc -eq 0 ]] || error "stat file should fail"
811 }
812 run_test 17o "stat file with incompat LMA feature"
813
814 test_18() {
815         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
816         ls $DIR || error "Failed to ls $DIR: $?"
817 }
818 run_test 18 "touch .../f ; ls ... =============================="
819
820 test_19a() {
821         touch $DIR/$tfile
822         ls -l $DIR
823         rm $DIR/$tfile
824         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
825 }
826 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
827
828 test_19b() {
829         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
830 }
831 run_test 19b "ls -l .../f19 (should return error) =============="
832
833 test_19c() {
834         [ $RUNAS_ID -eq $UID ] &&
835                 skip_env "RUNAS_ID = UID = $UID -- skipping"
836
837         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
838 }
839 run_test 19c "$RUNAS touch .../f19 (should return error) =="
840
841 test_19d() {
842         cat $DIR/f19 && error || true
843 }
844 run_test 19d "cat .../f19 (should return error) =============="
845
846 test_20() {
847         touch $DIR/$tfile
848         rm $DIR/$tfile
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         touch $DIR/$tfile
852         rm $DIR/$tfile
853         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
854 }
855 run_test 20 "touch .../f ; ls -l ..."
856
857 test_21() {
858         test_mkdir $DIR/$tdir
859         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
860         ln -s dangle $DIR/$tdir/link
861         echo foo >> $DIR/$tdir/link
862         cat $DIR/$tdir/dangle
863         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
864         $CHECKSTAT -f -t file $DIR/$tdir/link ||
865                 error "$tdir/link not linked to a file"
866 }
867 run_test 21 "write to dangling link"
868
869 test_22() {
870         local wdir=$DIR/$tdir
871         test_mkdir $wdir
872         chown $RUNAS_ID:$RUNAS_GID $wdir
873         (cd $wdir || error "cd $wdir failed";
874                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
875                 $RUNAS tar xf -)
876         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
877         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
878         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
879                 error "checkstat -u failed"
880 }
881 run_test 22 "unpack tar archive as non-root user"
882
883 # was test_23
884 test_23a() {
885         test_mkdir $DIR/$tdir
886         local file=$DIR/$tdir/$tfile
887
888         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
889         openfile -f O_CREAT:O_EXCL $file &&
890                 error "$file recreate succeeded" || true
891 }
892 run_test 23a "O_CREAT|O_EXCL in subdir"
893
894 test_23b() { # bug 18988
895         test_mkdir $DIR/$tdir
896         local file=$DIR/$tdir/$tfile
897
898         rm -f $file
899         echo foo > $file || error "write filed"
900         echo bar >> $file || error "append filed"
901         $CHECKSTAT -s 8 $file || error "wrong size"
902         rm $file
903 }
904 run_test 23b "O_APPEND check"
905
906 # LU-9409, size with O_APPEND and tiny writes
907 test_23c() {
908         local file=$DIR/$tfile
909
910         # single dd
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
912         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
913         rm -f $file
914
915         # racing tiny writes
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
918         wait
919         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
920         rm -f $file
921
922         #racing tiny & normal writes
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
925         wait
926         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
927         rm -f $file
928
929         #racing tiny & normal writes 2, ugly numbers
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
932         wait
933         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
934         rm -f $file
935 }
936 run_test 23c "O_APPEND size checks for tiny writes"
937
938 # LU-11069 file offset is correct after appending writes
939 test_23d() {
940         local file=$DIR/$tfile
941         local offset
942
943         echo CentaurHauls > $file
944         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
945         if ((offset != 26)); then
946                 error "wrong offset, expected 26, got '$offset'"
947         fi
948 }
949 run_test 23d "file offset is correct after appending writes"
950
951 # rename sanity
952 test_24a() {
953         echo '-- same directory rename'
954         test_mkdir $DIR/$tdir
955         touch $DIR/$tdir/$tfile.1
956         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
957         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
958 }
959 run_test 24a "rename file to non-existent target"
960
961 test_24b() {
962         test_mkdir $DIR/$tdir
963         touch $DIR/$tdir/$tfile.{1,2}
964         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
965         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
966         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
967 }
968 run_test 24b "rename file to existing target"
969
970 test_24c() {
971         test_mkdir $DIR/$tdir
972         test_mkdir $DIR/$tdir/d$testnum.1
973         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
974         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
975         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
976 }
977 run_test 24c "rename directory to non-existent target"
978
979 test_24d() {
980         test_mkdir -c1 $DIR/$tdir
981         test_mkdir -c1 $DIR/$tdir/d$testnum.1
982         test_mkdir -c1 $DIR/$tdir/d$testnum.2
983         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
984         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
985         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
986 }
987 run_test 24d "rename directory to existing target"
988
989 test_24e() {
990         echo '-- cross directory renames --'
991         test_mkdir $DIR/R5a
992         test_mkdir $DIR/R5b
993         touch $DIR/R5a/f
994         mv $DIR/R5a/f $DIR/R5b/g
995         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
996         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
997 }
998 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
999
1000 test_24f() {
1001         test_mkdir $DIR/R6a
1002         test_mkdir $DIR/R6b
1003         touch $DIR/R6a/f $DIR/R6b/g
1004         mv $DIR/R6a/f $DIR/R6b/g
1005         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1006         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1007 }
1008 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1009
1010 test_24g() {
1011         test_mkdir $DIR/R7a
1012         test_mkdir $DIR/R7b
1013         test_mkdir $DIR/R7a/d
1014         mv $DIR/R7a/d $DIR/R7b/e
1015         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1016         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1017 }
1018 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1019
1020 test_24h() {
1021         test_mkdir -c1 $DIR/R8a
1022         test_mkdir -c1 $DIR/R8b
1023         test_mkdir -c1 $DIR/R8a/d
1024         test_mkdir -c1 $DIR/R8b/e
1025         mrename $DIR/R8a/d $DIR/R8b/e
1026         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1027         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1028 }
1029 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1030
1031 test_24i() {
1032         echo "-- rename error cases"
1033         test_mkdir $DIR/R9
1034         test_mkdir $DIR/R9/a
1035         touch $DIR/R9/f
1036         mrename $DIR/R9/f $DIR/R9/a
1037         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1038         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1039         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1040 }
1041 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1042
1043 test_24j() {
1044         test_mkdir $DIR/R10
1045         mrename $DIR/R10/f $DIR/R10/g
1046         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1047         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1048         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1049 }
1050 run_test 24j "source does not exist ============================"
1051
1052 test_24k() {
1053         test_mkdir $DIR/R11a
1054         test_mkdir $DIR/R11a/d
1055         touch $DIR/R11a/f
1056         mv $DIR/R11a/f $DIR/R11a/d
1057         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1058         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1059 }
1060 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1061
1062 # bug 2429 - rename foo foo foo creates invalid file
1063 test_24l() {
1064         f="$DIR/f24l"
1065         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1066 }
1067 run_test 24l "Renaming a file to itself ========================"
1068
1069 test_24m() {
1070         f="$DIR/f24m"
1071         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1072         # on ext3 this does not remove either the source or target files
1073         # though the "expected" operation would be to remove the source
1074         $CHECKSTAT -t file ${f} || error "${f} missing"
1075         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1076 }
1077 run_test 24m "Renaming a file to a hard link to itself ========="
1078
1079 test_24n() {
1080     f="$DIR/f24n"
1081     # this stats the old file after it was renamed, so it should fail
1082     touch ${f}
1083     $CHECKSTAT ${f} || error "${f} missing"
1084     mv ${f} ${f}.rename
1085     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1086     $CHECKSTAT -a ${f} || error "${f} exists"
1087 }
1088 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1089
1090 test_24o() {
1091         test_mkdir $DIR/$tdir
1092         rename_many -s random -v -n 10 $DIR/$tdir
1093 }
1094 run_test 24o "rename of files during htree split"
1095
1096 test_24p() {
1097         test_mkdir $DIR/R12a
1098         test_mkdir $DIR/R12b
1099         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1100         mrename $DIR/R12a $DIR/R12b
1101         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1102         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1103         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1105 }
1106 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1107
1108 cleanup_multiop_pause() {
1109         trap 0
1110         kill -USR1 $MULTIPID
1111 }
1112
1113 test_24q() {
1114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1115
1116         test_mkdir $DIR/R13a
1117         test_mkdir $DIR/R13b
1118         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1119         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1120         MULTIPID=$!
1121
1122         trap cleanup_multiop_pause EXIT
1123         mrename $DIR/R13a $DIR/R13b
1124         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1125         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1126         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1127         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1128         cleanup_multiop_pause
1129         wait $MULTIPID || error "multiop close failed"
1130 }
1131 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1132
1133 test_24r() { #bug 3789
1134         test_mkdir $DIR/R14a
1135         test_mkdir $DIR/R14a/b
1136         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1137         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1138         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1139 }
1140 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1141
1142 test_24s() {
1143         test_mkdir $DIR/R15a
1144         test_mkdir $DIR/R15a/b
1145         test_mkdir $DIR/R15a/b/c
1146         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1147         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1148         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1149 }
1150 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4424 test_34a() {
4425         rm -f $DIR/f34
4426         $MCREATE $DIR/f34 || error "mcreate failed"
4427         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4428                 error "getstripe failed"
4429         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4430         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4431                 error "getstripe failed"
4432         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4433                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4434 }
4435 run_test 34a "truncate file that has not been opened ==========="
4436
4437 test_34b() {
4438         [ ! -f $DIR/f34 ] && test_34a
4439         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4440                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4441         $OPENFILE -f O_RDONLY $DIR/f34
4442         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4443                 error "getstripe failed"
4444         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4445                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4446 }
4447 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4448
4449 test_34c() {
4450         [ ! -f $DIR/f34 ] && test_34a
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453         $OPENFILE -f O_RDWR $DIR/f34
4454         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4455                 error "$LFS getstripe failed"
4456         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4457                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4458 }
4459 run_test 34c "O_RDWR opening file-with-size works =============="
4460
4461 test_34d() {
4462         [ ! -f $DIR/f34 ] && test_34a
4463         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4464                 error "dd failed"
4465         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4466                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4467         rm $DIR/f34
4468 }
4469 run_test 34d "write to sparse file ============================="
4470
4471 test_34e() {
4472         rm -f $DIR/f34e
4473         $MCREATE $DIR/f34e || error "mcreate failed"
4474         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4475         $CHECKSTAT -s 1000 $DIR/f34e ||
4476                 error "Size of $DIR/f34e not equal to 1000 bytes"
4477         $OPENFILE -f O_RDWR $DIR/f34e
4478         $CHECKSTAT -s 1000 $DIR/f34e ||
4479                 error "Size of $DIR/f34e not equal to 1000 bytes"
4480 }
4481 run_test 34e "create objects, some with size and some without =="
4482
4483 test_34f() { # bug 6242, 6243
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         SIZE34F=48000
4487         rm -f $DIR/f34f
4488         $MCREATE $DIR/f34f || error "mcreate failed"
4489         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4490         dd if=$DIR/f34f of=$TMP/f34f
4491         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4492         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4493         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4494         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4495         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4496 }
4497 run_test 34f "read from a file with no objects until EOF ======="
4498
4499 test_34g() {
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501
4502         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4503                 error "dd failed"
4504         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4505         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4506                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4507         cancel_lru_locks osc
4508         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4509                 error "wrong size after lock cancel"
4510
4511         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4512         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4513                 error "expanding truncate failed"
4514         cancel_lru_locks osc
4515         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4516                 error "wrong expanded size after lock cancel"
4517 }
4518 run_test 34g "truncate long file ==============================="
4519
4520 test_34h() {
4521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4522
4523         local gid=10
4524         local sz=1000
4525
4526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4527         sync # Flush the cache so that multiop below does not block on cache
4528              # flush when getting the group lock
4529         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4530         MULTIPID=$!
4531
4532         # Since just timed wait is not good enough, let's do a sync write
4533         # that way we are sure enough time for a roundtrip + processing
4534         # passed + 2 seconds of extra margin.
4535         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4536         rm $DIR/${tfile}-1
4537         sleep 2
4538
4539         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4540                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4541                 kill -9 $MULTIPID
4542         fi
4543         wait $MULTIPID
4544         local nsz=`stat -c %s $DIR/$tfile`
4545         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4546 }
4547 run_test 34h "ftruncate file under grouplock should not block"
4548
4549 test_35a() {
4550         cp /bin/sh $DIR/f35a
4551         chmod 444 $DIR/f35a
4552         chown $RUNAS_ID $DIR/f35a
4553         $RUNAS $DIR/f35a && error || true
4554         rm $DIR/f35a
4555 }
4556 run_test 35a "exec file with mode 444 (should return and not leak)"
4557
4558 test_36a() {
4559         rm -f $DIR/f36
4560         utime $DIR/f36 || error "utime failed for MDS"
4561 }
4562 run_test 36a "MDS utime check (mknod, utime)"
4563
4564 test_36b() {
4565         echo "" > $DIR/f36
4566         utime $DIR/f36 || error "utime failed for OST"
4567 }
4568 run_test 36b "OST utime check (open, utime)"
4569
4570 test_36c() {
4571         rm -f $DIR/d36/f36
4572         test_mkdir $DIR/d36
4573         chown $RUNAS_ID $DIR/d36
4574         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4575 }
4576 run_test 36c "non-root MDS utime check (mknod, utime)"
4577
4578 test_36d() {
4579         [ ! -d $DIR/d36 ] && test_36c
4580         echo "" > $DIR/d36/f36
4581         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4582 }
4583 run_test 36d "non-root OST utime check (open, utime)"
4584
4585 test_36e() {
4586         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4587
4588         test_mkdir $DIR/$tdir
4589         touch $DIR/$tdir/$tfile
4590         $RUNAS utime $DIR/$tdir/$tfile &&
4591                 error "utime worked, expected failure" || true
4592 }
4593 run_test 36e "utime on non-owned file (should return error)"
4594
4595 subr_36fh() {
4596         local fl="$1"
4597         local LANG_SAVE=$LANG
4598         local LC_LANG_SAVE=$LC_LANG
4599         export LANG=C LC_LANG=C # for date language
4600
4601         DATESTR="Dec 20  2000"
4602         test_mkdir $DIR/$tdir
4603         lctl set_param fail_loc=$fl
4604         date; date +%s
4605         cp /etc/hosts $DIR/$tdir/$tfile
4606         sync & # write RPC generated with "current" inode timestamp, but delayed
4607         sleep 1
4608         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4609         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4610         cancel_lru_locks $OSC
4611         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4612         date; date +%s
4613         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4614                 echo "BEFORE: $LS_BEFORE" && \
4615                 echo "AFTER : $LS_AFTER" && \
4616                 echo "WANT  : $DATESTR" && \
4617                 error "$DIR/$tdir/$tfile timestamps changed" || true
4618
4619         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4620 }
4621
4622 test_36f() {
4623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4624
4625         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4626         subr_36fh "0x80000214"
4627 }
4628 run_test 36f "utime on file racing with OST BRW write =========="
4629
4630 test_36g() {
4631         remote_ost_nodsh && skip "remote OST with nodsh"
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4634                 skip "Need MDS version at least 2.12.51"
4635
4636         local fmd_max_age
4637         local fmd
4638         local facet="ost1"
4639         local tgt="obdfilter"
4640
4641         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4642
4643         test_mkdir $DIR/$tdir
4644         fmd_max_age=$(do_facet $facet \
4645                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4646                 head -n 1")
4647
4648         echo "FMD max age: ${fmd_max_age}s"
4649         touch $DIR/$tdir/$tfile
4650         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4651                 gawk '{cnt=cnt+$1}  END{print cnt}')
4652         echo "FMD before: $fmd"
4653         [[ $fmd == 0 ]] &&
4654                 error "FMD wasn't create by touch"
4655         sleep $((fmd_max_age + 12))
4656         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4657                 gawk '{cnt=cnt+$1}  END{print cnt}')
4658         echo "FMD after: $fmd"
4659         [[ $fmd == 0 ]] ||
4660                 error "FMD wasn't expired by ping"
4661 }
4662 run_test 36g "FMD cache expiry ====================="
4663
4664 test_36h() {
4665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4666
4667         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4668         subr_36fh "0x80000227"
4669 }
4670 run_test 36h "utime on file racing with OST BRW write =========="
4671
4672 test_36i() {
4673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4674
4675         test_mkdir $DIR/$tdir
4676         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4677
4678         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4679         local new_mtime=$((mtime + 200))
4680
4681         #change Modify time of striped dir
4682         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4683                         error "change mtime failed"
4684
4685         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4686
4687         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4688 }
4689 run_test 36i "change mtime on striped directory"
4690
4691 # test_37 - duplicate with tests 32q 32r
4692
4693 test_38() {
4694         local file=$DIR/$tfile
4695         touch $file
4696         openfile -f O_DIRECTORY $file
4697         local RC=$?
4698         local ENOTDIR=20
4699         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4700         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4701 }
4702 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4703
4704 test_39a() { # was test_39
4705         touch $DIR/$tfile
4706         touch $DIR/${tfile}2
4707 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4708 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4710         sleep 2
4711         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4712         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4713                 echo "mtime"
4714                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4715                 echo "atime"
4716                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4717                 echo "ctime"
4718                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4719                 error "O_TRUNC didn't change timestamps"
4720         fi
4721 }
4722 run_test 39a "mtime changed on create"
4723
4724 test_39b() {
4725         test_mkdir -c1 $DIR/$tdir
4726         cp -p /etc/passwd $DIR/$tdir/fopen
4727         cp -p /etc/passwd $DIR/$tdir/flink
4728         cp -p /etc/passwd $DIR/$tdir/funlink
4729         cp -p /etc/passwd $DIR/$tdir/frename
4730         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4731
4732         sleep 1
4733         echo "aaaaaa" >> $DIR/$tdir/fopen
4734         echo "aaaaaa" >> $DIR/$tdir/flink
4735         echo "aaaaaa" >> $DIR/$tdir/funlink
4736         echo "aaaaaa" >> $DIR/$tdir/frename
4737
4738         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4739         local link_new=`stat -c %Y $DIR/$tdir/flink`
4740         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4741         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4742
4743         cat $DIR/$tdir/fopen > /dev/null
4744         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4745         rm -f $DIR/$tdir/funlink2
4746         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4750                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4751                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4752                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4753
4754                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4755                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4756                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4757                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39b "mtime change on open, link, unlink, rename  ======"
4764
4765 # this should be set to past
4766 TEST_39_MTIME=`date -d "1 year ago" +%s`
4767
4768 # bug 11063
4769 test_39c() {
4770         touch $DIR1/$tfile
4771         sleep 2
4772         local mtime0=`stat -c %Y $DIR1/$tfile`
4773
4774         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4775         local mtime1=`stat -c %Y $DIR1/$tfile`
4776         [ "$mtime1" = $TEST_39_MTIME ] || \
4777                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4778
4779         local d1=`date +%s`
4780         echo hello >> $DIR1/$tfile
4781         local d2=`date +%s`
4782         local mtime2=`stat -c %Y $DIR1/$tfile`
4783         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4784                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4785
4786         mv $DIR1/$tfile $DIR1/$tfile-1
4787
4788         for (( i=0; i < 2; i++ )) ; do
4789                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4790                 [ "$mtime2" = "$mtime3" ] || \
4791                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4792
4793                 cancel_lru_locks $OSC
4794                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4795         done
4796 }
4797 run_test 39c "mtime change on rename ==========================="
4798
4799 # bug 21114
4800 test_39d() {
4801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4802
4803         touch $DIR1/$tfile
4804         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4805
4806         for (( i=0; i < 2; i++ )) ; do
4807                 local mtime=`stat -c %Y $DIR1/$tfile`
4808                 [ $mtime = $TEST_39_MTIME ] || \
4809                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39d "create, utime, stat =============================="
4816
4817 # bug 21114
4818 test_39e() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         touch $DIR1/$tfile
4822         local mtime1=`stat -c %Y $DIR1/$tfile`
4823
4824         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4825
4826         for (( i=0; i < 2; i++ )) ; do
4827                 local mtime2=`stat -c %Y $DIR1/$tfile`
4828                 [ $mtime2 = $TEST_39_MTIME ] || \
4829                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4830
4831                 cancel_lru_locks $OSC
4832                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4833         done
4834 }
4835 run_test 39e "create, stat, utime, stat ========================"
4836
4837 # bug 21114
4838 test_39f() {
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840
4841         touch $DIR1/$tfile
4842         mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         sleep 2
4845         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4846
4847         for (( i=0; i < 2; i++ )) ; do
4848                 local mtime2=`stat -c %Y $DIR1/$tfile`
4849                 [ $mtime2 = $TEST_39_MTIME ] || \
4850                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4851
4852                 cancel_lru_locks $OSC
4853                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4854         done
4855 }
4856 run_test 39f "create, stat, sleep, utime, stat ================="
4857
4858 # bug 11063
4859 test_39g() {
4860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4861
4862         echo hello >> $DIR1/$tfile
4863         local mtime1=`stat -c %Y $DIR1/$tfile`
4864
4865         sleep 2
4866         chmod o+r $DIR1/$tfile
4867
4868         for (( i=0; i < 2; i++ )) ; do
4869                 local mtime2=`stat -c %Y $DIR1/$tfile`
4870                 [ "$mtime1" = "$mtime2" ] || \
4871                         error "lost mtime: $mtime2, should be $mtime1"
4872
4873                 cancel_lru_locks $OSC
4874                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4875         done
4876 }
4877 run_test 39g "write, chmod, stat ==============================="
4878
4879 # bug 11063
4880 test_39h() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         touch $DIR1/$tfile
4884         sleep 1
4885
4886         local d1=`date`
4887         echo hello >> $DIR1/$tfile
4888         local mtime1=`stat -c %Y $DIR1/$tfile`
4889
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891         local d2=`date`
4892         if [ "$d1" != "$d2" ]; then
4893                 echo "write and touch not within one second"
4894         else
4895                 for (( i=0; i < 2; i++ )) ; do
4896                         local mtime2=`stat -c %Y $DIR1/$tfile`
4897                         [ "$mtime2" = $TEST_39_MTIME ] || \
4898                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4899
4900                         cancel_lru_locks $OSC
4901                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902                 done
4903         fi
4904 }
4905 run_test 39h "write, utime within one second, stat ============="
4906
4907 test_39i() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         sleep 1
4912
4913         echo hello >> $DIR1/$tfile
4914         local mtime1=`stat -c %Y $DIR1/$tfile`
4915
4916         mv $DIR1/$tfile $DIR1/$tfile-1
4917
4918         for (( i=0; i < 2; i++ )) ; do
4919                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4920
4921                 [ "$mtime1" = "$mtime2" ] || \
4922                         error "lost mtime: $mtime2, should be $mtime1"
4923
4924                 cancel_lru_locks $OSC
4925                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4926         done
4927 }
4928 run_test 39i "write, rename, stat =============================="
4929
4930 test_39j() {
4931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4932
4933         start_full_debug_logging
4934         touch $DIR1/$tfile
4935         sleep 1
4936
4937         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4938         lctl set_param fail_loc=0x80000412
4939         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4940                 error "multiop failed"
4941         local multipid=$!
4942         local mtime1=`stat -c %Y $DIR1/$tfile`
4943
4944         mv $DIR1/$tfile $DIR1/$tfile-1
4945
4946         kill -USR1 $multipid
4947         wait $multipid || error "multiop close failed"
4948
4949         for (( i=0; i < 2; i++ )) ; do
4950                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4951                 [ "$mtime1" = "$mtime2" ] ||
4952                         error "mtime is lost on close: $mtime2, " \
4953                               "should be $mtime1"
4954
4955                 cancel_lru_locks
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958         lctl set_param fail_loc=0
4959         stop_full_debug_logging
4960 }
4961 run_test 39j "write, rename, close, stat ======================="
4962
4963 test_39k() {
4964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4965
4966         touch $DIR1/$tfile
4967         sleep 1
4968
4969         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4970         local multipid=$!
4971         local mtime1=`stat -c %Y $DIR1/$tfile`
4972
4973         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4974
4975         kill -USR1 $multipid
4976         wait $multipid || error "multiop close failed"
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile`
4980
4981                 [ "$mtime2" = $TEST_39_MTIME ] || \
4982                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4983
4984                 cancel_lru_locks
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39k "write, utime, close, stat ========================"
4989
4990 # this should be set to future
4991 TEST_39_ATIME=`date -d "1 year" +%s`
4992
4993 test_39l() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995         remote_mds_nodsh && skip "remote MDS with nodsh"
4996
4997         local atime_diff=$(do_facet $SINGLEMDS \
4998                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4999         rm -rf $DIR/$tdir
5000         mkdir_on_mdt0 $DIR/$tdir
5001
5002         # test setting directory atime to future
5003         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5004         local atime=$(stat -c %X $DIR/$tdir)
5005         [ "$atime" = $TEST_39_ATIME ] ||
5006                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5007
5008         # test setting directory atime from future to now
5009         local now=$(date +%s)
5010         touch -a -d @$now $DIR/$tdir
5011
5012         atime=$(stat -c %X $DIR/$tdir)
5013         [ "$atime" -eq "$now"  ] ||
5014                 error "atime is not updated from future: $atime, $now"
5015
5016         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5017         sleep 3
5018
5019         # test setting directory atime when now > dir atime + atime_diff
5020         local d1=$(date +%s)
5021         ls $DIR/$tdir
5022         local d2=$(date +%s)
5023         cancel_lru_locks mdc
5024         atime=$(stat -c %X $DIR/$tdir)
5025         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5026                 error "atime is not updated  : $atime, should be $d2"
5027
5028         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5029         sleep 3
5030
5031         # test not setting directory atime when now < dir atime + atime_diff
5032         ls $DIR/$tdir
5033         cancel_lru_locks mdc
5034         atime=$(stat -c %X $DIR/$tdir)
5035         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5036                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5037
5038         do_facet $SINGLEMDS \
5039                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5040 }
5041 run_test 39l "directory atime update ==========================="
5042
5043 test_39m() {
5044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5045
5046         touch $DIR1/$tfile
5047         sleep 2
5048         local far_past_mtime=$(date -d "May 29 1953" +%s)
5049         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5050
5051         touch -m -d @$far_past_mtime $DIR1/$tfile
5052         touch -a -d @$far_past_atime $DIR1/$tfile
5053
5054         for (( i=0; i < 2; i++ )) ; do
5055                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5056                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5057                         error "atime or mtime set incorrectly"
5058
5059                 cancel_lru_locks $OSC
5060                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5061         done
5062 }
5063 run_test 39m "test atime and mtime before 1970"
5064
5065 test_39n() { # LU-3832
5066         remote_mds_nodsh && skip "remote MDS with nodsh"
5067
5068         local atime_diff=$(do_facet $SINGLEMDS \
5069                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5070         local atime0
5071         local atime1
5072         local atime2
5073
5074         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5075
5076         rm -rf $DIR/$tfile
5077         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5078         atime0=$(stat -c %X $DIR/$tfile)
5079
5080         sleep 5
5081         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5082         atime1=$(stat -c %X $DIR/$tfile)
5083
5084         sleep 5
5085         cancel_lru_locks mdc
5086         cancel_lru_locks osc
5087         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5088         atime2=$(stat -c %X $DIR/$tfile)
5089
5090         do_facet $SINGLEMDS \
5091                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5092
5093         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5094         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5095 }
5096 run_test 39n "check that O_NOATIME is honored"
5097
5098 test_39o() {
5099         TESTDIR=$DIR/$tdir/$tfile
5100         [ -e $TESTDIR ] && rm -rf $TESTDIR
5101         mkdir -p $TESTDIR
5102         cd $TESTDIR
5103         links1=2
5104         ls
5105         mkdir a b
5106         ls
5107         links2=$(stat -c %h .)
5108         [ $(($links1 + 2)) != $links2 ] &&
5109                 error "wrong links count $(($links1 + 2)) != $links2"
5110         rmdir b
5111         links3=$(stat -c %h .)
5112         [ $(($links1 + 1)) != $links3 ] &&
5113                 error "wrong links count $links1 != $links3"
5114         return 0
5115 }
5116 run_test 39o "directory cached attributes updated after create"
5117
5118 test_39p() {
5119         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5120
5121         local MDTIDX=1
5122         TESTDIR=$DIR/$tdir/$tdir
5123         [ -e $TESTDIR ] && rm -rf $TESTDIR
5124         test_mkdir -p $TESTDIR
5125         cd $TESTDIR
5126         links1=2
5127         ls
5128         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5130         ls
5131         links2=$(stat -c %h .)
5132         [ $(($links1 + 2)) != $links2 ] &&
5133                 error "wrong links count $(($links1 + 2)) != $links2"
5134         rmdir remote_dir2
5135         links3=$(stat -c %h .)
5136         [ $(($links1 + 1)) != $links3 ] &&
5137                 error "wrong links count $links1 != $links3"
5138         return 0
5139 }
5140 run_test 39p "remote directory cached attributes updated after create ========"
5141
5142 test_39r() {
5143         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5144                 skip "no atime update on old OST"
5145         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5146                 skip_env "ldiskfs only test"
5147         fi
5148
5149         local saved_adiff
5150         saved_adiff=$(do_facet ost1 \
5151                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5152         stack_trap "do_facet ost1 \
5153                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5154
5155         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5156
5157         $LFS setstripe -i 0 $DIR/$tfile
5158         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5159                 error "can't write initial file"
5160         cancel_lru_locks osc
5161
5162         # exceed atime_diff and access file
5163         sleep 10
5164         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5165                 error "can't udpate atime"
5166
5167         local atime_cli=$(stat -c %X $DIR/$tfile)
5168         echo "client atime: $atime_cli"
5169         # allow atime update to be written to device
5170         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5171         sleep 5
5172
5173         local ostdev=$(ostdevname 1)
5174         local fid=($(lfs getstripe -y $DIR/$tfile |
5175                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5176         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5177         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5178
5179         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5180         local atime_ost=$(do_facet ost1 "$cmd" |&
5181                           awk -F'[: ]' '/atime:/ { print $4 }')
5182         (( atime_cli == atime_ost )) ||
5183                 error "atime on client $atime_cli != ost $atime_ost"
5184 }
5185 run_test 39r "lazy atime update on OST"
5186
5187 test_39q() { # LU-8041
5188         local testdir=$DIR/$tdir
5189         mkdir -p $testdir
5190         multiop_bg_pause $testdir D_c || error "multiop failed"
5191         local multipid=$!
5192         cancel_lru_locks mdc
5193         kill -USR1 $multipid
5194         local atime=$(stat -c %X $testdir)
5195         [ "$atime" -ne 0 ] || error "atime is zero"
5196 }
5197 run_test 39q "close won't zero out atime"
5198
5199 test_40() {
5200         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5201         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5202                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5203         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5204                 error "$tfile is not 4096 bytes in size"
5205 }
5206 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5207
5208 test_41() {
5209         # bug 1553
5210         small_write $DIR/f41 18
5211 }
5212 run_test 41 "test small file write + fstat ====================="
5213
5214 count_ost_writes() {
5215         lctl get_param -n ${OSC}.*.stats |
5216                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5217                         END { printf("%0.0f", writes) }'
5218 }
5219
5220 # decent default
5221 WRITEBACK_SAVE=500
5222 DIRTY_RATIO_SAVE=40
5223 MAX_DIRTY_RATIO=50
5224 BG_DIRTY_RATIO_SAVE=10
5225 MAX_BG_DIRTY_RATIO=25
5226
5227 start_writeback() {
5228         trap 0
5229         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5230         # dirty_ratio, dirty_background_ratio
5231         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5232                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5233                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5234                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5235         else
5236                 # if file not here, we are a 2.4 kernel
5237                 kill -CONT `pidof kupdated`
5238         fi
5239 }
5240
5241 stop_writeback() {
5242         # setup the trap first, so someone cannot exit the test at the
5243         # exact wrong time and mess up a machine
5244         trap start_writeback EXIT
5245         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5246         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5247                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5248                 sysctl -w vm.dirty_writeback_centisecs=0
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 # save and increase /proc/sys/vm/dirty_ratio
5251                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5252                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5253                 # save and increase /proc/sys/vm/dirty_background_ratio
5254                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5255                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5256         else
5257                 # if file not here, we are a 2.4 kernel
5258                 kill -STOP `pidof kupdated`
5259         fi
5260 }
5261
5262 # ensure that all stripes have some grant before we test client-side cache
5263 setup_test42() {
5264         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5265                 dd if=/dev/zero of=$i bs=4k count=1
5266                 rm $i
5267         done
5268 }
5269
5270 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5271 # file truncation, and file removal.
5272 test_42a() {
5273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5274
5275         setup_test42
5276         cancel_lru_locks $OSC
5277         stop_writeback
5278         sync; sleep 1; sync # just to be safe
5279         BEFOREWRITES=`count_ost_writes`
5280         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5281         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5282         AFTERWRITES=`count_ost_writes`
5283         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5284                 error "$BEFOREWRITES < $AFTERWRITES"
5285         start_writeback
5286 }
5287 run_test 42a "ensure that we don't flush on close"
5288
5289 test_42b() {
5290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5291
5292         setup_test42
5293         cancel_lru_locks $OSC
5294         stop_writeback
5295         sync
5296         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5297         BEFOREWRITES=$(count_ost_writes)
5298         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5299         AFTERWRITES=$(count_ost_writes)
5300         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5301                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5302         fi
5303         BEFOREWRITES=$(count_ost_writes)
5304         sync || error "sync: $?"
5305         AFTERWRITES=$(count_ost_writes)
5306         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5307                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5308         fi
5309         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5310         start_writeback
5311         return 0
5312 }
5313 run_test 42b "test destroy of file with cached dirty data ======"
5314
5315 # if these tests just want to test the effect of truncation,
5316 # they have to be very careful.  consider:
5317 # - the first open gets a {0,EOF}PR lock
5318 # - the first write conflicts and gets a {0, count-1}PW
5319 # - the rest of the writes are under {count,EOF}PW
5320 # - the open for truncate tries to match a {0,EOF}PR
5321 #   for the filesize and cancels the PWs.
5322 # any number of fixes (don't get {0,EOF} on open, match
5323 # composite locks, do smarter file size management) fix
5324 # this, but for now we want these tests to verify that
5325 # the cancellation with truncate intent works, so we
5326 # start the file with a full-file pw lock to match against
5327 # until the truncate.
5328 trunc_test() {
5329         test=$1
5330         file=$DIR/$test
5331         offset=$2
5332         cancel_lru_locks $OSC
5333         stop_writeback
5334         # prime the file with 0,EOF PW to match
5335         touch $file
5336         $TRUNCATE $file 0
5337         sync; sync
5338         # now the real test..
5339         dd if=/dev/zero of=$file bs=1024 count=100
5340         BEFOREWRITES=`count_ost_writes`
5341         $TRUNCATE $file $offset
5342         cancel_lru_locks $OSC
5343         AFTERWRITES=`count_ost_writes`
5344         start_writeback
5345 }
5346
5347 test_42c() {
5348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5349
5350         trunc_test 42c 1024
5351         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5352                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5353         rm $file
5354 }
5355 run_test 42c "test partial truncate of file with cached dirty data"
5356
5357 test_42d() {
5358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5359
5360         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5361         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5362         $LCTL set_param debug=+cache
5363
5364         trunc_test 42d 0
5365         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5366                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5367         rm $file
5368 }
5369 run_test 42d "test complete truncate of file with cached dirty data"
5370
5371 test_42e() { # bug22074
5372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5373
5374         local TDIR=$DIR/${tdir}e
5375         local pages=16 # hardcoded 16 pages, don't change it.
5376         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5377         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5378         local max_dirty_mb
5379         local warmup_files
5380
5381         test_mkdir $DIR/${tdir}e
5382         $LFS setstripe -c 1 $TDIR
5383         createmany -o $TDIR/f $files
5384
5385         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5386
5387         # we assume that with $OSTCOUNT files, at least one of them will
5388         # be allocated on OST0.
5389         warmup_files=$((OSTCOUNT * max_dirty_mb))
5390         createmany -o $TDIR/w $warmup_files
5391
5392         # write a large amount of data into one file and sync, to get good
5393         # avail_grant number from OST.
5394         for ((i=0; i<$warmup_files; i++)); do
5395                 idx=$($LFS getstripe -i $TDIR/w$i)
5396                 [ $idx -ne 0 ] && continue
5397                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5398                 break
5399         done
5400         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5401         sync
5402         $LCTL get_param $proc_osc0/cur_dirty_bytes
5403         $LCTL get_param $proc_osc0/cur_grant_bytes
5404
5405         # create as much dirty pages as we can while not to trigger the actual
5406         # RPCs directly. but depends on the env, VFS may trigger flush during this
5407         # period, hopefully we are good.
5408         for ((i=0; i<$warmup_files; i++)); do
5409                 idx=$($LFS getstripe -i $TDIR/w$i)
5410                 [ $idx -ne 0 ] && continue
5411                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5412         done
5413         $LCTL get_param $proc_osc0/cur_dirty_bytes
5414         $LCTL get_param $proc_osc0/cur_grant_bytes
5415
5416         # perform the real test
5417         $LCTL set_param $proc_osc0/rpc_stats 0
5418         for ((;i<$files; i++)); do
5419                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5420                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5421         done
5422         sync
5423         $LCTL get_param $proc_osc0/rpc_stats
5424
5425         local percent=0
5426         local have_ppr=false
5427         $LCTL get_param $proc_osc0/rpc_stats |
5428                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5429                         # skip lines until we are at the RPC histogram data
5430                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5431                         $have_ppr || continue
5432
5433                         # we only want the percent stat for < 16 pages
5434                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5435
5436                         percent=$((percent + WPCT))
5437                         if [[ $percent -gt 15 ]]; then
5438                                 error "less than 16-pages write RPCs" \
5439                                       "$percent% > 15%"
5440                                 break
5441                         fi
5442                 done
5443         rm -rf $TDIR
5444 }
5445 run_test 42e "verify sub-RPC writes are not done synchronously"
5446
5447 test_43A() { # was test_43
5448         test_mkdir $DIR/$tdir
5449         cp -p /bin/ls $DIR/$tdir/$tfile
5450         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5451         pid=$!
5452         # give multiop a chance to open
5453         sleep 1
5454
5455         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5456         kill -USR1 $pid
5457         # Wait for multiop to exit
5458         wait $pid
5459 }
5460 run_test 43A "execution of file opened for write should return -ETXTBSY"
5461
5462 test_43a() {
5463         test_mkdir $DIR/$tdir
5464         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5465         $DIR/$tdir/sleep 60 &
5466         SLEEP_PID=$!
5467         # Make sure exec of $tdir/sleep wins race with truncate
5468         sleep 1
5469         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5470         kill $SLEEP_PID
5471 }
5472 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5473
5474 test_43b() {
5475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5476
5477         test_mkdir $DIR/$tdir
5478         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5479         $DIR/$tdir/sleep 60 &
5480         SLEEP_PID=$!
5481         # Make sure exec of $tdir/sleep wins race with truncate
5482         sleep 1
5483         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5484         kill $SLEEP_PID
5485 }
5486 run_test 43b "truncate of file being executed should return -ETXTBSY"
5487
5488 test_43c() {
5489         local testdir="$DIR/$tdir"
5490         test_mkdir $testdir
5491         cp $SHELL $testdir/
5492         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5493                 ( cd $testdir && md5sum -c )
5494 }
5495 run_test 43c "md5sum of copy into lustre"
5496
5497 test_44A() { # was test_44
5498         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5499
5500         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5501         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5502 }
5503 run_test 44A "zero length read from a sparse stripe"
5504
5505 test_44a() {
5506         local nstripe=$($LFS getstripe -c -d $DIR)
5507         [ -z "$nstripe" ] && skip "can't get stripe info"
5508         [[ $nstripe -gt $OSTCOUNT ]] &&
5509                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5510
5511         local stride=$($LFS getstripe -S -d $DIR)
5512         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5513                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5514         fi
5515
5516         OFFSETS="0 $((stride/2)) $((stride-1))"
5517         for offset in $OFFSETS; do
5518                 for i in $(seq 0 $((nstripe-1))); do
5519                         local GLOBALOFFSETS=""
5520                         # size in Bytes
5521                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5522                         local myfn=$DIR/d44a-$size
5523                         echo "--------writing $myfn at $size"
5524                         ll_sparseness_write $myfn $size ||
5525                                 error "ll_sparseness_write"
5526                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5527                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5528                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5529
5530                         for j in $(seq 0 $((nstripe-1))); do
5531                                 # size in Bytes
5532                                 size=$((((j + $nstripe )*$stride + $offset)))
5533                                 ll_sparseness_write $myfn $size ||
5534                                         error "ll_sparseness_write"
5535                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5536                         done
5537                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5538                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5539                         rm -f $myfn
5540                 done
5541         done
5542 }
5543 run_test 44a "test sparse pwrite ==============================="
5544
5545 dirty_osc_total() {
5546         tot=0
5547         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5548                 tot=$(($tot + $d))
5549         done
5550         echo $tot
5551 }
5552 do_dirty_record() {
5553         before=`dirty_osc_total`
5554         echo executing "\"$*\""
5555         eval $*
5556         after=`dirty_osc_total`
5557         echo before $before, after $after
5558 }
5559 test_45() {
5560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5561
5562         f="$DIR/f45"
5563         # Obtain grants from OST if it supports it
5564         echo blah > ${f}_grant
5565         stop_writeback
5566         sync
5567         do_dirty_record "echo blah > $f"
5568         [[ $before -eq $after ]] && error "write wasn't cached"
5569         do_dirty_record "> $f"
5570         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5571         do_dirty_record "echo blah > $f"
5572         [[ $before -eq $after ]] && error "write wasn't cached"
5573         do_dirty_record "sync"
5574         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5575         do_dirty_record "echo blah > $f"
5576         [[ $before -eq $after ]] && error "write wasn't cached"
5577         do_dirty_record "cancel_lru_locks osc"
5578         [[ $before -gt $after ]] ||
5579                 error "lock cancellation didn't lower dirty count"
5580         start_writeback
5581 }
5582 run_test 45 "osc io page accounting ============================"
5583
5584 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5585 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5586 # objects offset and an assert hit when an rpc was built with 1023's mapped
5587 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5588 test_46() {
5589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5590
5591         f="$DIR/f46"
5592         stop_writeback
5593         sync
5594         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5597         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5598         sync
5599         start_writeback
5600 }
5601 run_test 46 "dirtying a previously written page ================"
5602
5603 # test_47 is removed "Device nodes check" is moved to test_28
5604
5605 test_48a() { # bug 2399
5606         [ "$mds1_FSTYPE" = "zfs" ] &&
5607         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5608                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5609
5610         test_mkdir $DIR/$tdir
5611         cd $DIR/$tdir
5612         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5613         test_mkdir $DIR/$tdir
5614         touch foo || error "'touch foo' failed after recreating cwd"
5615         test_mkdir bar
5616         touch .foo || error "'touch .foo' failed after recreating cwd"
5617         test_mkdir .bar
5618         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5619         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5620         cd . || error "'cd .' failed after recreating cwd"
5621         mkdir . && error "'mkdir .' worked after recreating cwd"
5622         rmdir . && error "'rmdir .' worked after recreating cwd"
5623         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5624         cd .. || error "'cd ..' failed after recreating cwd"
5625 }
5626 run_test 48a "Access renamed working dir (should return errors)="
5627
5628 test_48b() { # bug 2399
5629         rm -rf $DIR/$tdir
5630         test_mkdir $DIR/$tdir
5631         cd $DIR/$tdir
5632         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5633         touch foo && error "'touch foo' worked after removing cwd"
5634         mkdir foo && error "'mkdir foo' worked after removing cwd"
5635         touch .foo && error "'touch .foo' worked after removing cwd"
5636         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5637         ls . > /dev/null && error "'ls .' worked after removing cwd"
5638         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5639         mkdir . && error "'mkdir .' worked after removing cwd"
5640         rmdir . && error "'rmdir .' worked after removing cwd"
5641         ln -s . foo && error "'ln -s .' worked after removing cwd"
5642         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5643 }
5644 run_test 48b "Access removed working dir (should return errors)="
5645
5646 test_48c() { # bug 2350
5647         #lctl set_param debug=-1
5648         #set -vx
5649         rm -rf $DIR/$tdir
5650         test_mkdir -p $DIR/$tdir/dir
5651         cd $DIR/$tdir/dir
5652         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5653         $TRACE touch foo && error "touch foo worked after removing cwd"
5654         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5655         touch .foo && error "touch .foo worked after removing cwd"
5656         mkdir .foo && error "mkdir .foo worked after removing cwd"
5657         $TRACE ls . && error "'ls .' worked after removing cwd"
5658         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5659         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5660         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5661         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5662         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5663 }
5664 run_test 48c "Access removed working subdir (should return errors)"
5665
5666 test_48d() { # bug 2350
5667         #lctl set_param debug=-1
5668         #set -vx
5669         rm -rf $DIR/$tdir
5670         test_mkdir -p $DIR/$tdir/dir
5671         cd $DIR/$tdir/dir
5672         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5673         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5674         $TRACE touch foo && error "'touch foo' worked after removing parent"
5675         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5676         touch .foo && error "'touch .foo' worked after removing parent"
5677         mkdir .foo && error "mkdir .foo worked after removing parent"
5678         $TRACE ls . && error "'ls .' worked after removing parent"
5679         $TRACE ls .. && error "'ls ..' worked after removing parent"
5680         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5681         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5682         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5683         true
5684 }
5685 run_test 48d "Access removed parent subdir (should return errors)"
5686
5687 test_48e() { # bug 4134
5688         #lctl set_param debug=-1
5689         #set -vx
5690         rm -rf $DIR/$tdir
5691         test_mkdir -p $DIR/$tdir/dir
5692         cd $DIR/$tdir/dir
5693         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5694         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5695         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5696         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5697         # On a buggy kernel addition of "touch foo" after cd .. will
5698         # produce kernel oops in lookup_hash_it
5699         touch ../foo && error "'cd ..' worked after recreate parent"
5700         cd $DIR
5701         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5702 }
5703 run_test 48e "Access to recreated parent subdir (should return errors)"
5704
5705 test_48f() {
5706         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5707                 skip "need MDS >= 2.13.55"
5708         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5709         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5710                 skip "needs different host for mdt1 mdt2"
5711         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5712
5713         $LFS mkdir -i0 $DIR/$tdir
5714         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5715
5716         for d in sub1 sub2 sub3; do
5717                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5718                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5719                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5720         done
5721
5722         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5723 }
5724 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5725
5726 test_49() { # LU-1030
5727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5728         remote_ost_nodsh && skip "remote OST with nodsh"
5729
5730         # get ost1 size - $FSNAME-OST0000
5731         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5732                 awk '{ print $4 }')
5733         # write 800M at maximum
5734         [[ $ost1_size -lt 2 ]] && ost1_size=2
5735         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5736
5737         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5738         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5739         local dd_pid=$!
5740
5741         # change max_pages_per_rpc while writing the file
5742         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5743         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5744         # loop until dd process exits
5745         while ps ax -opid | grep -wq $dd_pid; do
5746                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5747                 sleep $((RANDOM % 5 + 1))
5748         done
5749         # restore original max_pages_per_rpc
5750         $LCTL set_param $osc1_mppc=$orig_mppc
5751         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5752 }
5753 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5754
5755 test_50() {
5756         # bug 1485
5757         test_mkdir $DIR/$tdir
5758         cd $DIR/$tdir
5759         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5760 }
5761 run_test 50 "special situations: /proc symlinks  ==============="
5762
5763 test_51a() {    # was test_51
5764         # bug 1516 - create an empty entry right after ".." then split dir
5765         test_mkdir -c1 $DIR/$tdir
5766         touch $DIR/$tdir/foo
5767         $MCREATE $DIR/$tdir/bar
5768         rm $DIR/$tdir/foo
5769         createmany -m $DIR/$tdir/longfile 201
5770         FNUM=202
5771         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5772                 $MCREATE $DIR/$tdir/longfile$FNUM
5773                 FNUM=$(($FNUM + 1))
5774                 echo -n "+"
5775         done
5776         echo
5777         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5778 }
5779 run_test 51a "special situations: split htree with empty entry =="
5780
5781 cleanup_print_lfs_df () {
5782         trap 0
5783         $LFS df
5784         $LFS df -i
5785 }
5786
5787 test_51b() {
5788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5789
5790         local dir=$DIR/$tdir
5791         local nrdirs=$((65536 + 100))
5792
5793         # cleanup the directory
5794         rm -fr $dir
5795
5796         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5797
5798         $LFS df
5799         $LFS df -i
5800         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5801         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5802         [[ $numfree -lt $nrdirs ]] &&
5803                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5804
5805         # need to check free space for the directories as well
5806         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5807         numfree=$(( blkfree / $(fs_inode_ksize) ))
5808         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5809
5810         trap cleanup_print_lfs_df EXIT
5811
5812         # create files
5813         createmany -d $dir/d $nrdirs || {
5814                 unlinkmany $dir/d $nrdirs
5815                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5816         }
5817
5818         # really created :
5819         nrdirs=$(ls -U $dir | wc -l)
5820
5821         # unlink all but 100 subdirectories, then check it still works
5822         local left=100
5823         local delete=$((nrdirs - left))
5824
5825         $LFS df
5826         $LFS df -i
5827
5828         # for ldiskfs the nlink count should be 1, but this is OSD specific
5829         # and so this is listed for informational purposes only
5830         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5831         unlinkmany -d $dir/d $delete ||
5832                 error "unlink of first $delete subdirs failed"
5833
5834         echo "nlink between: $(stat -c %h $dir)"
5835         local found=$(ls -U $dir | wc -l)
5836         [ $found -ne $left ] &&
5837                 error "can't find subdirs: found only $found, expected $left"
5838
5839         unlinkmany -d $dir/d $delete $left ||
5840                 error "unlink of second $left subdirs failed"
5841         # regardless of whether the backing filesystem tracks nlink accurately
5842         # or not, the nlink count shouldn't be more than "." and ".." here
5843         local after=$(stat -c %h $dir)
5844         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5845                 echo "nlink after: $after"
5846
5847         cleanup_print_lfs_df
5848 }
5849 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5850
5851 test_51d_sub() {
5852         local stripecount=$1
5853         local nfiles=$2
5854
5855         log "create files with stripecount=$stripecount"
5856         $LFS setstripe -C $stripecount $DIR/$tdir
5857         createmany -o $DIR/$tdir/t- $nfiles
5858         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5859         for ((n = 0; n < $OSTCOUNT; n++)); do
5860                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5861                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5862                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5863                             '($1 == '$n') { objs += 1 } \
5864                             END { printf("%0.0f", objs) }')
5865                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5866         done
5867         unlinkmany $DIR/$tdir/t- $nfiles
5868         rm  -f $TMP/$tfile
5869
5870         local nlast
5871         local min=4
5872         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5873
5874         # For some combinations of stripecount and OSTCOUNT current code
5875         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5876         # than others. Rather than skipping this test entirely, check that
5877         # and keep testing to ensure imbalance does not get worse. LU-15282
5878         (( (OSTCOUNT == 6 && stripecount == 4) ||
5879            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5880            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5881         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5882                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5883                         { $LFS df && $LFS df -i &&
5884                         error "stripecount=$stripecount: " \
5885                               "OST $n has fewer objects vs. OST $nlast " \
5886                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5887                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5888                         { $LFS df && $LFS df -i &&
5889                         error "stripecount=$stripecount: " \
5890                               "OST $n has more objects vs. OST $nlast " \
5891                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5892
5893                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5894                         { $LFS df && $LFS df -i &&
5895                         error "stripecount=$stripecount: " \
5896                               "OST $n has fewer #0 objects vs. OST $nlast " \
5897                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5898                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5899                         { $LFS df && $LFS df -i &&
5900                         error "stripecount=$stripecount: " \
5901                               "OST $n has more #0 objects vs. OST $nlast " \
5902                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5903         done
5904 }
5905
5906 test_51d() {
5907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5908         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5909
5910         local stripecount
5911         local per_ost=100
5912         local nfiles=$((per_ost * OSTCOUNT))
5913         local mdts=$(comma_list $(mdts_nodes))
5914         local param="osp.*.create_count"
5915         local qos_old=$(do_facet mds1 \
5916                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5917
5918         do_nodes $mdts \
5919                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5920         stack_trap "do_nodes $mdts \
5921                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5922
5923         test_mkdir $DIR/$tdir
5924         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5925         (( dirstripes > 0 )) || dirstripes=1
5926
5927         # Ensure enough OST objects precreated for tests to pass without
5928         # running out of objects.  This is an LOV r-r OST algorithm test,
5929         # not an OST object precreation test.
5930         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5931         (( old >= nfiles )) ||
5932         {
5933                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5934
5935                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5936                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5937
5938                 # trigger precreation from all MDTs for all OSTs
5939                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5940                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5941                 done
5942         }
5943
5944         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5945                 sleep 8  # allow object precreation to catch up
5946                 test_51d_sub $stripecount $nfiles
5947         done
5948 }
5949 run_test 51d "check LOV round-robin OST object distribution"
5950
5951 test_51e() {
5952         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5953                 skip_env "ldiskfs only test"
5954         fi
5955
5956         test_mkdir -c1 $DIR/$tdir
5957         test_mkdir -c1 $DIR/$tdir/d0
5958
5959         touch $DIR/$tdir/d0/foo
5960         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5961                 error "file exceed 65000 nlink limit!"
5962         unlinkmany $DIR/$tdir/d0/f- 65001
5963         return 0
5964 }
5965 run_test 51e "check file nlink limit"
5966
5967 test_51f() {
5968         test_mkdir $DIR/$tdir
5969
5970         local max=100000
5971         local ulimit_old=$(ulimit -n)
5972         local spare=20 # number of spare fd's for scripts/libraries, etc.
5973         local mdt=$($LFS getstripe -m $DIR/$tdir)
5974         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5975
5976         echo "MDT$mdt numfree=$numfree, max=$max"
5977         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5978         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5979                 while ! ulimit -n $((numfree + spare)); do
5980                         numfree=$((numfree * 3 / 4))
5981                 done
5982                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5983         else
5984                 echo "left ulimit at $ulimit_old"
5985         fi
5986
5987         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5988                 unlinkmany $DIR/$tdir/f $numfree
5989                 error "create+open $numfree files in $DIR/$tdir failed"
5990         }
5991         ulimit -n $ulimit_old
5992
5993         # if createmany exits at 120s there will be fewer than $numfree files
5994         unlinkmany $DIR/$tdir/f $numfree || true
5995 }
5996 run_test 51f "check many open files limit"
5997
5998 test_52a() {
5999         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6000         test_mkdir $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6003         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6004         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6005         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6006         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6007                                         error "link worked"
6008         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6009         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6010         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6011                                                      error "lsattr"
6012         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6013         cp -r $DIR/$tdir $TMP/
6014         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6015 }
6016 run_test 52a "append-only flag test (should return errors)"
6017
6018 test_52b() {
6019         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6020         test_mkdir $DIR/$tdir
6021         touch $DIR/$tdir/foo
6022         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6023         cat test > $DIR/$tdir/foo && error "cat test worked"
6024         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6025         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6026         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6027                                         error "link worked"
6028         echo foo >> $DIR/$tdir/foo && error "echo worked"
6029         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6030         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6031         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6032         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6033                                                         error "lsattr"
6034         chattr -i $DIR/$tdir/foo || error "chattr failed"
6035
6036         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6037 }
6038 run_test 52b "immutable flag test (should return errors) ======="
6039
6040 test_53() {
6041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6042         remote_mds_nodsh && skip "remote MDS with nodsh"
6043         remote_ost_nodsh && skip "remote OST with nodsh"
6044
6045         local param
6046         local param_seq
6047         local ostname
6048         local mds_last
6049         local mds_last_seq
6050         local ost_last
6051         local ost_last_seq
6052         local ost_last_id
6053         local ostnum
6054         local node
6055         local found=false
6056         local support_last_seq=true
6057
6058         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6059                 support_last_seq=false
6060
6061         # only test MDT0000
6062         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6063         local value
6064         for value in $(do_facet $SINGLEMDS \
6065                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6066                 param=$(echo ${value[0]} | cut -d "=" -f1)
6067                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6068
6069                 if $support_last_seq; then
6070                         param_seq=$(echo $param |
6071                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6072                         mds_last_seq=$(do_facet $SINGLEMDS \
6073                                        $LCTL get_param -n $param_seq)
6074                 fi
6075                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6076
6077                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6078                 node=$(facet_active_host ost$((ostnum+1)))
6079                 param="obdfilter.$ostname.last_id"
6080                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6081                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6082                         ost_last_id=$ost_last
6083
6084                         if $support_last_seq; then
6085                                 ost_last_id=$(echo $ost_last |
6086                                               awk -F':' '{print $2}' |
6087                                               sed -e "s/^0x//g")
6088                                 ost_last_seq=$(echo $ost_last |
6089                                                awk -F':' '{print $1}')
6090                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6091                         fi
6092
6093                         if [[ $ost_last_id != $mds_last ]]; then
6094                                 error "$ost_last_id != $mds_last"
6095                         else
6096                                 found=true
6097                                 break
6098                         fi
6099                 done
6100         done
6101         $found || error "can not match last_seq/last_id for $mdtosc"
6102         return 0
6103 }
6104 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6105
6106 test_54a() {
6107         perl -MSocket -e ';' || skip "no Socket perl module installed"
6108
6109         $SOCKETSERVER $DIR/socket ||
6110                 error "$SOCKETSERVER $DIR/socket failed: $?"
6111         $SOCKETCLIENT $DIR/socket ||
6112                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6113         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6114 }
6115 run_test 54a "unix domain socket test =========================="
6116
6117 test_54b() {
6118         f="$DIR/f54b"
6119         mknod $f c 1 3
6120         chmod 0666 $f
6121         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6122 }
6123 run_test 54b "char device works in lustre ======================"
6124
6125 find_loop_dev() {
6126         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6127         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6128         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6129
6130         for i in $(seq 3 7); do
6131                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6132                 LOOPDEV=$LOOPBASE$i
6133                 LOOPNUM=$i
6134                 break
6135         done
6136 }
6137
6138 cleanup_54c() {
6139         local rc=0
6140         loopdev="$DIR/loop54c"
6141
6142         trap 0
6143         $UMOUNT $DIR/$tdir || rc=$?
6144         losetup -d $loopdev || true
6145         losetup -d $LOOPDEV || true
6146         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6147         return $rc
6148 }
6149
6150 test_54c() {
6151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6152
6153         loopdev="$DIR/loop54c"
6154
6155         find_loop_dev
6156         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6157         trap cleanup_54c EXIT
6158         mknod $loopdev b 7 $LOOPNUM
6159         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6161         losetup $loopdev $DIR/$tfile ||
6162                 error "can't set up $loopdev for $DIR/$tfile"
6163         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6164         test_mkdir $DIR/$tdir
6165         mount -t ext2 $loopdev $DIR/$tdir ||
6166                 error "error mounting $loopdev on $DIR/$tdir"
6167         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6168                 error "dd write"
6169         df $DIR/$tdir
6170         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6171                 error "dd read"
6172         cleanup_54c
6173 }
6174 run_test 54c "block device works in lustre ====================="
6175
6176 test_54d() {
6177         local pipe="$DIR/$tfile.pipe"
6178         local string="aaaaaa"
6179
6180         mknod $pipe p
6181         echo -n "$string" > $pipe &
6182         local result=$(cat $pipe)
6183         [[ "$result" == "$string" ]] || error "$result != $string"
6184 }
6185 run_test 54d "fifo device works in lustre ======================"
6186
6187 test_54e() {
6188         f="$DIR/f54e"
6189         string="aaaaaa"
6190         cp -aL /dev/console $f
6191         echo $string > $f || error "echo $string to $f failed"
6192 }
6193 run_test 54e "console/tty device works in lustre ======================"
6194
6195 test_56a() {
6196         local numfiles=3
6197         local numdirs=2
6198         local dir=$DIR/$tdir
6199
6200         rm -rf $dir
6201         test_mkdir -p $dir/dir
6202         for i in $(seq $numfiles); do
6203                 touch $dir/file$i
6204                 touch $dir/dir/file$i
6205         done
6206
6207         local numcomp=$($LFS getstripe --component-count $dir)
6208
6209         [[ $numcomp == 0 ]] && numcomp=1
6210
6211         # test lfs getstripe with --recursive
6212         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6213
6214         [[ $filenum -eq $((numfiles * 2)) ]] ||
6215                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6216         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6217         [[ $filenum -eq $numfiles ]] ||
6218                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6219         echo "$LFS getstripe showed obdidx or l_ost_idx"
6220
6221         # test lfs getstripe with file instead of dir
6222         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6223         [[ $filenum -eq 1 ]] ||
6224                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6225         echo "$LFS getstripe file1 passed"
6226
6227         #test lfs getstripe with --verbose
6228         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6229         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6230                 error "$LFS getstripe --verbose $dir: "\
6231                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6232         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6233                 error "$LFS getstripe $dir: showed lmm_magic"
6234
6235         #test lfs getstripe with -v prints lmm_fid
6236         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6237         local countfids=$((numdirs + numfiles * numcomp))
6238         [[ $filenum -eq $countfids ]] ||
6239                 error "$LFS getstripe -v $dir: "\
6240                       "got $filenum want $countfids lmm_fid"
6241         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6242                 error "$LFS getstripe $dir: showed lmm_fid by default"
6243         echo "$LFS getstripe --verbose passed"
6244
6245         #check for FID information
6246         local fid1=$($LFS getstripe --fid $dir/file1)
6247         local fid2=$($LFS getstripe --verbose $dir/file1 |
6248                      awk '/lmm_fid: / { print $2; exit; }')
6249         local fid3=$($LFS path2fid $dir/file1)
6250
6251         [ "$fid1" != "$fid2" ] &&
6252                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6253         [ "$fid1" != "$fid3" ] &&
6254                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6255         echo "$LFS getstripe --fid passed"
6256
6257         #test lfs getstripe with --obd
6258         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6259                 error "$LFS getstripe --obd wrong_uuid: should return error"
6260
6261         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6262
6263         local ostidx=1
6264         local obduuid=$(ostuuid_from_index $ostidx)
6265         local found=$($LFS getstripe -r --obd $obduuid $dir |
6266                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6267
6268         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6269         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6270                 ((filenum--))
6271         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6272                 ((filenum--))
6273
6274         [[ $found -eq $filenum ]] ||
6275                 error "$LFS getstripe --obd: found $found expect $filenum"
6276         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6277                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6278                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6279                 error "$LFS getstripe --obd: should not show file on other obd"
6280         echo "$LFS getstripe --obd passed"
6281 }
6282 run_test 56a "check $LFS getstripe"
6283
6284 test_56b() {
6285         local dir=$DIR/$tdir
6286         local numdirs=3
6287
6288         test_mkdir $dir
6289         for i in $(seq $numdirs); do
6290                 test_mkdir $dir/dir$i
6291         done
6292
6293         # test lfs getdirstripe default mode is non-recursion, which is
6294         # different from lfs getstripe
6295         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6296
6297         [[ $dircnt -eq 1 ]] ||
6298                 error "$LFS getdirstripe: found $dircnt, not 1"
6299         dircnt=$($LFS getdirstripe --recursive $dir |
6300                 grep -c lmv_stripe_count)
6301         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6302                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6303 }
6304 run_test 56b "check $LFS getdirstripe"
6305
6306 test_56c() {
6307         remote_ost_nodsh && skip "remote OST with nodsh"
6308
6309         local ost_idx=0
6310         local ost_name=$(ostname_from_index $ost_idx)
6311         local old_status=$(ost_dev_status $ost_idx)
6312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6313
6314         [[ -z "$old_status" ]] ||
6315                 skip_env "OST $ost_name is in $old_status status"
6316
6317         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6318         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6319                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6320         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6321                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6322                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6323         fi
6324
6325         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6326                 error "$LFS df -v showing inactive devices"
6327         sleep_maxage
6328
6329         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6330
6331         [[ "$new_status" =~ "D" ]] ||
6332                 error "$ost_name status is '$new_status', missing 'D'"
6333         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6334                 [[ "$new_status" =~ "N" ]] ||
6335                         error "$ost_name status is '$new_status', missing 'N'"
6336         fi
6337         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6338                 [[ "$new_status" =~ "f" ]] ||
6339                         error "$ost_name status is '$new_status', missing 'f'"
6340         fi
6341
6342         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6343         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6344                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6345         [[ -z "$p" ]] && restore_lustre_params < $p || true
6346         sleep_maxage
6347
6348         new_status=$(ost_dev_status $ost_idx)
6349         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6350                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6351         # can't check 'f' as devices may actually be on flash
6352 }
6353 run_test 56c "check 'lfs df' showing device status"
6354
6355 test_56d() {
6356         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6357         local osts=$($LFS df -v $MOUNT | grep -c OST)
6358
6359         $LFS df $MOUNT
6360
6361         (( mdts == MDSCOUNT )) ||
6362                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6363         (( osts == OSTCOUNT )) ||
6364                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6365 }
6366 run_test 56d "'lfs df -v' prints only configured devices"
6367
6368 test_56e() {
6369         err_enoent=2 # No such file or directory
6370         err_eopnotsupp=95 # Operation not supported
6371
6372         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6373         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6374
6375         # Check for handling of path not exists
6376         output=$($LFS df $enoent_mnt 2>&1)
6377         ret=$?
6378
6379         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6380         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6381                 error "expect failure $err_enoent, not $ret"
6382
6383         # Check for handling of non-Lustre FS
6384         output=$($LFS df $notsup_mnt)
6385         ret=$?
6386
6387         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6388         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6389                 error "expect success $err_eopnotsupp, not $ret"
6390
6391         # Check for multiple LustreFS argument
6392         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6393         ret=$?
6394
6395         [[ $output -eq 3 && $ret -eq 0 ]] ||
6396                 error "expect success 3, not $output, rc = $ret"
6397
6398         # Check for correct non-Lustre FS handling among multiple
6399         # LustreFS argument
6400         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6401                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6402         ret=$?
6403
6404         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6405                 error "expect success 2, not $output, rc = $ret"
6406 }
6407 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6408
6409 NUMFILES=3
6410 NUMDIRS=3
6411 setup_56() {
6412         local local_tdir="$1"
6413         local local_numfiles="$2"
6414         local local_numdirs="$3"
6415         local dir_params="$4"
6416         local dir_stripe_params="$5"
6417
6418         if [ ! -d "$local_tdir" ] ; then
6419                 test_mkdir -p $dir_stripe_params $local_tdir
6420                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6421                 for i in $(seq $local_numfiles) ; do
6422                         touch $local_tdir/file$i
6423                 done
6424                 for i in $(seq $local_numdirs) ; do
6425                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6426                         for j in $(seq $local_numfiles) ; do
6427                                 touch $local_tdir/dir$i/file$j
6428                         done
6429                 done
6430         fi
6431 }
6432
6433 setup_56_special() {
6434         local local_tdir=$1
6435         local local_numfiles=$2
6436         local local_numdirs=$3
6437
6438         setup_56 $local_tdir $local_numfiles $local_numdirs
6439
6440         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6441                 for i in $(seq $local_numfiles) ; do
6442                         mknod $local_tdir/loop${i}b b 7 $i
6443                         mknod $local_tdir/null${i}c c 1 3
6444                         ln -s $local_tdir/file1 $local_tdir/link${i}
6445                 done
6446                 for i in $(seq $local_numdirs) ; do
6447                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6448                         mknod $local_tdir/dir$i/null${i}c c 1 3
6449                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6450                 done
6451         fi
6452 }
6453
6454 test_56g() {
6455         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6456         local expected=$(($NUMDIRS + 2))
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         # test lfs find with -name
6461         for i in $(seq $NUMFILES) ; do
6462                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6463
6464                 [ $nums -eq $expected ] ||
6465                         error "lfs find -name '*$i' $dir wrong: "\
6466                               "found $nums, expected $expected"
6467         done
6468 }
6469 run_test 56g "check lfs find -name"
6470
6471 test_56h() {
6472         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6473         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6474
6475         setup_56 $dir $NUMFILES $NUMDIRS
6476
6477         # test lfs find with ! -name
6478         for i in $(seq $NUMFILES) ; do
6479                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6480
6481                 [ $nums -eq $expected ] ||
6482                         error "lfs find ! -name '*$i' $dir wrong: "\
6483                               "found $nums, expected $expected"
6484         done
6485 }
6486 run_test 56h "check lfs find ! -name"
6487
6488 test_56i() {
6489         local dir=$DIR/$tdir
6490
6491         test_mkdir $dir
6492
6493         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6494         local out=$($cmd)
6495
6496         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6497 }
6498 run_test 56i "check 'lfs find -ost UUID' skips directories"
6499
6500 test_56j() {
6501         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6502
6503         setup_56_special $dir $NUMFILES $NUMDIRS
6504
6505         local expected=$((NUMDIRS + 1))
6506         local cmd="$LFS find -type d $dir"
6507         local nums=$($cmd | wc -l)
6508
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511 }
6512 run_test 56j "check lfs find -type d"
6513
6514 test_56k() {
6515         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6516
6517         setup_56_special $dir $NUMFILES $NUMDIRS
6518
6519         local expected=$(((NUMDIRS + 1) * NUMFILES))
6520         local cmd="$LFS find -type f $dir"
6521         local nums=$($cmd | wc -l)
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525 }
6526 run_test 56k "check lfs find -type f"
6527
6528 test_56l() {
6529         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6530
6531         setup_56_special $dir $NUMFILES $NUMDIRS
6532
6533         local expected=$((NUMDIRS + NUMFILES))
6534         local cmd="$LFS find -type b $dir"
6535         local nums=$($cmd | wc -l)
6536
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539 }
6540 run_test 56l "check lfs find -type b"
6541
6542 test_56m() {
6543         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6544
6545         setup_56_special $dir $NUMFILES $NUMDIRS
6546
6547         local expected=$((NUMDIRS + NUMFILES))
6548         local cmd="$LFS find -type c $dir"
6549         local nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552 }
6553 run_test 56m "check lfs find -type c"
6554
6555 test_56n() {
6556         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type l $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56n "check lfs find -type l"
6567
6568 test_56o() {
6569         local dir=$DIR/$tdir
6570
6571         setup_56 $dir $NUMFILES $NUMDIRS
6572         utime $dir/file1 > /dev/null || error "utime (1)"
6573         utime $dir/file2 > /dev/null || error "utime (2)"
6574         utime $dir/dir1 > /dev/null || error "utime (3)"
6575         utime $dir/dir2 > /dev/null || error "utime (4)"
6576         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6577         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6578
6579         local expected=4
6580         local nums=$($LFS find -mtime +0 $dir | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6584
6585         expected=12
6586         cmd="$LFS find -mtime 0 $dir"
6587         nums=$($cmd | wc -l)
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590 }
6591 run_test 56o "check lfs find -mtime for old files"
6592
6593 test_56ob() {
6594         local dir=$DIR/$tdir
6595         local expected=1
6596         local count=0
6597
6598         # just to make sure there is something that won't be found
6599         test_mkdir $dir
6600         touch $dir/$tfile.now
6601
6602         for age in year week day hour min; do
6603                 count=$((count + 1))
6604
6605                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6606                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6607                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6608
6609                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6610                 local nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613
6614                 cmd="$LFS find $dir -atime $count${age:0:1}"
6615                 nums=$($cmd | wc -l)
6616                 [ $nums -eq $expected ] ||
6617                         error "'$cmd' wrong: found $nums, expected $expected"
6618         done
6619
6620         sleep 2
6621         cmd="$LFS find $dir -ctime +1s -type f"
6622         nums=$($cmd | wc -l)
6623         (( $nums == $count * 2 + 1)) ||
6624                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6625 }
6626 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6627
6628 test_newerXY_base() {
6629         local x=$1
6630         local y=$2
6631         local dir=$DIR/$tdir
6632         local ref
6633         local negref
6634
6635         if [ $y == "t" ]; then
6636                 if [ $x == "b" ]; then
6637                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6638                 else
6639                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6640                 fi
6641         else
6642                 ref=$DIR/$tfile.newer.$x$y
6643                 touch $ref || error "touch $ref failed"
6644         fi
6645
6646         echo "before = $ref"
6647         sleep 2
6648         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6649         sleep 2
6650         if [ $y == "t" ]; then
6651                 if [ $x == "b" ]; then
6652                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6653                 else
6654                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6655                 fi
6656         else
6657                 negref=$DIR/$tfile.negnewer.$x$y
6658                 touch $negref || error "touch $negref failed"
6659         fi
6660
6661         echo "after = $negref"
6662         local cmd="$LFS find $dir -newer$x$y $ref"
6663         local nums=$(eval $cmd | wc -l)
6664         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6665
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6673
6674         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6675         nums=$(eval $cmd | wc -l)
6676         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6677                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6678
6679         rm -rf $DIR/*
6680 }
6681
6682 test_56oc() {
6683         test_newerXY_base "a" "a"
6684         test_newerXY_base "a" "m"
6685         test_newerXY_base "a" "c"
6686         test_newerXY_base "m" "a"
6687         test_newerXY_base "m" "m"
6688         test_newerXY_base "m" "c"
6689         test_newerXY_base "c" "a"
6690         test_newerXY_base "c" "m"
6691         test_newerXY_base "c" "c"
6692
6693         [[ -n "$sles_version" ]] &&
6694                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6695
6696         test_newerXY_base "a" "t"
6697         test_newerXY_base "m" "t"
6698         test_newerXY_base "c" "t"
6699
6700         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6701            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6702                 ! btime_supported && echo "btime unsupported" && return 0
6703
6704         test_newerXY_base "b" "b"
6705         test_newerXY_base "b" "t"
6706 }
6707 run_test 56oc "check lfs find -newerXY work"
6708
6709 btime_supported() {
6710         local dir=$DIR/$tdir
6711         local rc
6712
6713         mkdir -p $dir
6714         touch $dir/$tfile
6715         $LFS find $dir -btime -1d -type f
6716         rc=$?
6717         rm -rf $dir
6718         return $rc
6719 }
6720
6721 test_56od() {
6722         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6723                 ! btime_supported && skip "btime unsupported on MDS"
6724
6725         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6726                 ! btime_supported && skip "btime unsupported on clients"
6727
6728         local dir=$DIR/$tdir
6729         local ref=$DIR/$tfile.ref
6730         local negref=$DIR/$tfile.negref
6731
6732         mkdir $dir || error "mkdir $dir failed"
6733         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6734         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6735         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6736         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6737         touch $ref || error "touch $ref failed"
6738         # sleep 3 seconds at least
6739         sleep 3
6740
6741         local before=$(do_facet mds1 date +%s)
6742         local skew=$(($(date +%s) - before + 1))
6743
6744         if (( skew < 0 && skew > -5 )); then
6745                 sleep $((0 - skew + 1))
6746                 skew=0
6747         fi
6748
6749         # Set the dir stripe params to limit files all on MDT0,
6750         # otherwise we need to calc the max clock skew between
6751         # the client and MDTs.
6752         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6753         sleep 2
6754         touch $negref || error "touch $negref failed"
6755
6756         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6757         local nums=$($cmd | wc -l)
6758         local expected=$(((NUMFILES + 1) * NUMDIRS))
6759
6760         [ $nums -eq $expected ] ||
6761                 error "'$cmd' wrong: found $nums, expected $expected"
6762
6763         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6764         nums=$($cmd | wc -l)
6765         expected=$((NUMFILES + 1))
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768
6769         [ $skew -lt 0 ] && return
6770
6771         local after=$(do_facet mds1 date +%s)
6772         local age=$((after - before + 1 + skew))
6773
6774         cmd="$LFS find $dir -btime -${age}s -type f"
6775         nums=$($cmd | wc -l)
6776         expected=$(((NUMFILES + 1) * NUMDIRS))
6777
6778         echo "Clock skew between client and server: $skew, age:$age"
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781
6782         expected=$(($NUMDIRS + 1))
6783         cmd="$LFS find $dir -btime -${age}s -type d"
6784         nums=$($cmd | wc -l)
6785         [ $nums -eq $expected ] ||
6786                 error "'$cmd' wrong: found $nums, expected $expected"
6787         rm -f $ref $negref || error "Failed to remove $ref $negref"
6788 }
6789 run_test 56od "check lfs find -btime with units"
6790
6791 test_56p() {
6792         [ $RUNAS_ID -eq $UID ] &&
6793                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6794
6795         local dir=$DIR/$tdir
6796
6797         setup_56 $dir $NUMFILES $NUMDIRS
6798         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6799
6800         local expected=$NUMFILES
6801         local cmd="$LFS find -uid $RUNAS_ID $dir"
6802         local nums=$($cmd | wc -l)
6803
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6808         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56p "check lfs find -uid and ! -uid"
6814
6815 test_56q() {
6816         [ $RUNAS_ID -eq $UID ] &&
6817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6818
6819         local dir=$DIR/$tdir
6820
6821         setup_56 $dir $NUMFILES $NUMDIRS
6822         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6823
6824         local expected=$NUMFILES
6825         local cmd="$LFS find -gid $RUNAS_GID $dir"
6826         local nums=$($cmd | wc -l)
6827
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830
6831         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6832         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6833         nums=$($cmd | wc -l)
6834         [ $nums -eq $expected ] ||
6835                 error "'$cmd' wrong: found $nums, expected $expected"
6836 }
6837 run_test 56q "check lfs find -gid and ! -gid"
6838
6839 test_56r() {
6840         local dir=$DIR/$tdir
6841
6842         setup_56 $dir $NUMFILES $NUMDIRS
6843
6844         local expected=12
6845         local cmd="$LFS find -size 0 -type f -lazy $dir"
6846         local nums=$($cmd | wc -l)
6847
6848         [ $nums -eq $expected ] ||
6849                 error "'$cmd' wrong: found $nums, expected $expected"
6850         cmd="$LFS find -size 0 -type f $dir"
6851         nums=$($cmd | wc -l)
6852         [ $nums -eq $expected ] ||
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854
6855         expected=0
6856         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860         cmd="$LFS find ! -size 0 -type f $dir"
6861         nums=$($cmd | wc -l)
6862         [ $nums -eq $expected ] ||
6863                 error "'$cmd' wrong: found $nums, expected $expected"
6864
6865         echo "test" > $dir/$tfile
6866         echo "test2" > $dir/$tfile.2 && sync
6867         expected=1
6868         cmd="$LFS find -size 5 -type f -lazy $dir"
6869         nums=$($cmd | wc -l)
6870         [ $nums -eq $expected ] ||
6871                 error "'$cmd' wrong: found $nums, expected $expected"
6872         cmd="$LFS find -size 5 -type f $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876
6877         expected=1
6878         cmd="$LFS find -size +5 -type f -lazy $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882         cmd="$LFS find -size +5 -type f $dir"
6883         nums=$($cmd | wc -l)
6884         [ $nums -eq $expected ] ||
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886
6887         expected=2
6888         cmd="$LFS find -size +0 -type f -lazy $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892         cmd="$LFS find -size +0 -type f $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896
6897         expected=2
6898         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902         cmd="$LFS find ! -size -5 -type f $dir"
6903         nums=$($cmd | wc -l)
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906
6907         expected=12
6908         cmd="$LFS find -size -5 -type f -lazy $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912         cmd="$LFS find -size -5 -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916 }
6917 run_test 56r "check lfs find -size works"
6918
6919 test_56ra_sub() {
6920         local expected=$1
6921         local glimpses=$2
6922         local cmd="$3"
6923
6924         cancel_lru_locks $OSC
6925
6926         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6927         local nums=$($cmd | wc -l)
6928
6929         [ $nums -eq $expected ] ||
6930                 error "'$cmd' wrong: found $nums, expected $expected"
6931
6932         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6933
6934         if (( rpcs_before + glimpses != rpcs_after )); then
6935                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6936                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6937
6938                 if [[ $glimpses == 0 ]]; then
6939                         error "'$cmd' should not send glimpse RPCs to OST"
6940                 else
6941                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6942                 fi
6943         fi
6944 }
6945
6946 test_56ra() {
6947         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6948                 skip "MDS < 2.12.58 doesn't return LSOM data"
6949         local dir=$DIR/$tdir
6950         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6951
6952         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6953
6954         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6955         $LCTL set_param -n llite.*.statahead_agl=0
6956         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6957
6958         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6959         # open and close all files to ensure LSOM is updated
6960         cancel_lru_locks $OSC
6961         find $dir -type f | xargs cat > /dev/null
6962
6963         #   expect_found  glimpse_rpcs  command_to_run
6964         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6965         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6966         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6967         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6968
6969         echo "test" > $dir/$tfile
6970         echo "test2" > $dir/$tfile.2 && sync
6971         cancel_lru_locks $OSC
6972         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6973
6974         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6975         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6976         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6977         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6978
6979         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6980         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6981         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6982         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6983         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6984         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6985 }
6986 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6987
6988 test_56rb() {
6989         local dir=$DIR/$tdir
6990         local tmp=$TMP/$tfile.log
6991         local mdt_idx;
6992
6993         test_mkdir -p $dir || error "failed to mkdir $dir"
6994         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6995                 error "failed to setstripe $dir/$tfile"
6996         mdt_idx=$($LFS getdirstripe -i $dir)
6997         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6998
6999         stack_trap "rm -f $tmp" EXIT
7000         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7001         ! grep -q obd_uuid $tmp ||
7002                 error "failed to find --size +100K --ost 0 $dir"
7003         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7004         ! grep -q obd_uuid $tmp ||
7005                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7006 }
7007 run_test 56rb "check lfs find --size --ost/--mdt works"
7008
7009 test_56rc() {
7010         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7011         local dir=$DIR/$tdir
7012         local found
7013
7014         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7015         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7016         (( $MDSCOUNT > 2 )) &&
7017                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7018         mkdir $dir/$tdir-{1..10}
7019         touch $dir/$tfile-{1..10}
7020
7021         found=$($LFS find $dir --mdt-count 2 | wc -l)
7022         expect=11
7023         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7024
7025         found=$($LFS find $dir -T +1 | wc -l)
7026         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7027         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7028
7029         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7030         expect=11
7031         (( $found == $expect )) || error "found $found all_char, expect $expect"
7032
7033         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7034         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7035         (( $found == $expect )) || error "found $found all_char, expect $expect"
7036 }
7037 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7038
7039 test_56s() { # LU-611 #LU-9369
7040         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7041
7042         local dir=$DIR/$tdir
7043         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7044
7045         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7046         for i in $(seq $NUMDIRS); do
7047                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7048         done
7049
7050         local expected=$NUMDIRS
7051         local cmd="$LFS find -c $OSTCOUNT $dir"
7052         local nums=$($cmd | wc -l)
7053
7054         [ $nums -eq $expected ] || {
7055                 $LFS getstripe -R $dir
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057         }
7058
7059         expected=$((NUMDIRS + onestripe))
7060         cmd="$LFS find -stripe-count +0 -type f $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] || {
7063                 $LFS getstripe -R $dir
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065         }
7066
7067         expected=$onestripe
7068         cmd="$LFS find -stripe-count 1 -type f $dir"
7069         nums=$($cmd | wc -l)
7070         [ $nums -eq $expected ] || {
7071                 $LFS getstripe -R $dir
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073         }
7074
7075         cmd="$LFS find -stripe-count -2 -type f $dir"
7076         nums=$($cmd | wc -l)
7077         [ $nums -eq $expected ] || {
7078                 $LFS getstripe -R $dir
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         }
7081
7082         expected=0
7083         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7084         nums=$($cmd | wc -l)
7085         [ $nums -eq $expected ] || {
7086                 $LFS getstripe -R $dir
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         }
7089 }
7090 run_test 56s "check lfs find -stripe-count works"
7091
7092 test_56t() { # LU-611 #LU-9369
7093         local dir=$DIR/$tdir
7094
7095         setup_56 $dir 0 $NUMDIRS
7096         for i in $(seq $NUMDIRS); do
7097                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7098         done
7099
7100         local expected=$NUMDIRS
7101         local cmd="$LFS find -S 8M $dir"
7102         local nums=$($cmd | wc -l)
7103
7104         [ $nums -eq $expected ] || {
7105                 $LFS getstripe -R $dir
7106                 error "'$cmd' wrong: found $nums, expected $expected"
7107         }
7108         rm -rf $dir
7109
7110         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7111
7112         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7113
7114         expected=$(((NUMDIRS + 1) * NUMFILES))
7115         cmd="$LFS find -stripe-size 512k -type f $dir"
7116         nums=$($cmd | wc -l)
7117         [ $nums -eq $expected ] ||
7118                 error "'$cmd' wrong: found $nums, expected $expected"
7119
7120         cmd="$LFS find -stripe-size +320k -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7126         cmd="$LFS find -stripe-size +200k -type f $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130
7131         cmd="$LFS find -stripe-size -640k -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         expected=4
7137         cmd="$LFS find -stripe-size 256k -type f $dir"
7138         nums=$($cmd | wc -l)
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141
7142         cmd="$LFS find -stripe-size -320k -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146
7147         expected=0
7148         cmd="$LFS find -stripe-size 1024k -type f $dir"
7149         nums=$($cmd | wc -l)
7150         [ $nums -eq $expected ] ||
7151                 error "'$cmd' wrong: found $nums, expected $expected"
7152 }
7153 run_test 56t "check lfs find -stripe-size works"
7154
7155 test_56u() { # LU-611
7156         local dir=$DIR/$tdir
7157
7158         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7159
7160         if [[ $OSTCOUNT -gt 1 ]]; then
7161                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7162                 onestripe=4
7163         else
7164                 onestripe=0
7165         fi
7166
7167         local expected=$(((NUMDIRS + 1) * NUMFILES))
7168         local cmd="$LFS find -stripe-index 0 -type f $dir"
7169         local nums=$($cmd | wc -l)
7170
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173
7174         expected=$onestripe
7175         cmd="$LFS find -stripe-index 1 -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7181         nums=$($cmd | wc -l)
7182         [ $nums -eq $expected ] ||
7183                 error "'$cmd' wrong: found $nums, expected $expected"
7184
7185         expected=0
7186         # This should produce an error and not return any files
7187         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7188         nums=$($cmd 2>/dev/null | wc -l)
7189         [ $nums -eq $expected ] ||
7190                 error "'$cmd' wrong: found $nums, expected $expected"
7191
7192         if [[ $OSTCOUNT -gt 1 ]]; then
7193                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7194                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7195                 nums=$($cmd | wc -l)
7196                 [ $nums -eq $expected ] ||
7197                         error "'$cmd' wrong: found $nums, expected $expected"
7198         fi
7199 }
7200 run_test 56u "check lfs find -stripe-index works"
7201
7202 test_56v() {
7203         local mdt_idx=0
7204         local dir=$DIR/$tdir
7205
7206         setup_56 $dir $NUMFILES $NUMDIRS
7207
7208         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7209         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7210
7211         for file in $($LFS find -m $UUID $dir); do
7212                 file_midx=$($LFS getstripe -m $file)
7213                 [ $file_midx -eq $mdt_idx ] ||
7214                         error "lfs find -m $UUID != getstripe -m $file_midx"
7215         done
7216 }
7217 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7218
7219 test_56w() {
7220         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7222
7223         local dir=$DIR/$tdir
7224
7225         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7226
7227         local stripe_size=$($LFS getstripe -S -d $dir) ||
7228                 error "$LFS getstripe -S -d $dir failed"
7229         stripe_size=${stripe_size%% *}
7230
7231         local file_size=$((stripe_size * OSTCOUNT))
7232         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7233         local required_space=$((file_num * file_size))
7234         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7235                            head -n1)
7236         [[ $free_space -le $((required_space / 1024)) ]] &&
7237                 skip_env "need $required_space, have $free_space kbytes"
7238
7239         local dd_bs=65536
7240         local dd_count=$((file_size / dd_bs))
7241
7242         # write data into the files
7243         local i
7244         local j
7245         local file
7246
7247         for i in $(seq $NUMFILES); do
7248                 file=$dir/file$i
7249                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7250                         error "write data into $file failed"
7251         done
7252         for i in $(seq $NUMDIRS); do
7253                 for j in $(seq $NUMFILES); do
7254                         file=$dir/dir$i/file$j
7255                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7256                                 error "write data into $file failed"
7257                 done
7258         done
7259
7260         # $LFS_MIGRATE will fail if hard link migration is unsupported
7261         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7262                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7263                         error "creating links to $dir/dir1/file1 failed"
7264         fi
7265
7266         local expected=-1
7267
7268         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7269
7270         # lfs_migrate file
7271         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7272
7273         echo "$cmd"
7274         eval $cmd || error "$cmd failed"
7275
7276         check_stripe_count $dir/file1 $expected
7277
7278         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7279         then
7280                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7281                 # OST 1 if it is on OST 0. This file is small enough to
7282                 # be on only one stripe.
7283                 file=$dir/migr_1_ost
7284                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7285                         error "write data into $file failed"
7286                 local obdidx=$($LFS getstripe -i $file)
7287                 local oldmd5=$(md5sum $file)
7288                 local newobdidx=0
7289
7290                 [[ $obdidx -eq 0 ]] && newobdidx=1
7291                 cmd="$LFS migrate -i $newobdidx $file"
7292                 echo $cmd
7293                 eval $cmd || error "$cmd failed"
7294
7295                 local realobdix=$($LFS getstripe -i $file)
7296                 local newmd5=$(md5sum $file)
7297
7298                 [[ $newobdidx -ne $realobdix ]] &&
7299                         error "new OST is different (was=$obdidx, "\
7300                               "wanted=$newobdidx, got=$realobdix)"
7301                 [[ "$oldmd5" != "$newmd5" ]] &&
7302                         error "md5sum differ: $oldmd5, $newmd5"
7303         fi
7304
7305         # lfs_migrate dir
7306         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7307         echo "$cmd"
7308         eval $cmd || error "$cmd failed"
7309
7310         for j in $(seq $NUMFILES); do
7311                 check_stripe_count $dir/dir1/file$j $expected
7312         done
7313
7314         # lfs_migrate works with lfs find
7315         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7316              $LFS_MIGRATE -y -c $expected"
7317         echo "$cmd"
7318         eval $cmd || error "$cmd failed"
7319
7320         for i in $(seq 2 $NUMFILES); do
7321                 check_stripe_count $dir/file$i $expected
7322         done
7323         for i in $(seq 2 $NUMDIRS); do
7324                 for j in $(seq $NUMFILES); do
7325                 check_stripe_count $dir/dir$i/file$j $expected
7326                 done
7327         done
7328 }
7329 run_test 56w "check lfs_migrate -c stripe_count works"
7330
7331 test_56wb() {
7332         local file1=$DIR/$tdir/file1
7333         local create_pool=false
7334         local initial_pool=$($LFS getstripe -p $DIR)
7335         local pool_list=()
7336         local pool=""
7337
7338         echo -n "Creating test dir..."
7339         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7340         echo "done."
7341
7342         echo -n "Creating test file..."
7343         touch $file1 || error "cannot create file"
7344         echo "done."
7345
7346         echo -n "Detecting existing pools..."
7347         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7348
7349         if [ ${#pool_list[@]} -gt 0 ]; then
7350                 echo "${pool_list[@]}"
7351                 for thispool in "${pool_list[@]}"; do
7352                         if [[ -z "$initial_pool" ||
7353                               "$initial_pool" != "$thispool" ]]; then
7354                                 pool="$thispool"
7355                                 echo "Using existing pool '$pool'"
7356                                 break
7357                         fi
7358                 done
7359         else
7360                 echo "none detected."
7361         fi
7362         if [ -z "$pool" ]; then
7363                 pool=${POOL:-testpool}
7364                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7365                 echo -n "Creating pool '$pool'..."
7366                 create_pool=true
7367                 pool_add $pool &> /dev/null ||
7368                         error "pool_add failed"
7369                 echo "done."
7370
7371                 echo -n "Adding target to pool..."
7372                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7373                         error "pool_add_targets failed"
7374                 echo "done."
7375         fi
7376
7377         echo -n "Setting pool using -p option..."
7378         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7379                 error "migrate failed rc = $?"
7380         echo "done."
7381
7382         echo -n "Verifying test file is in pool after migrating..."
7383         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7384                 error "file was not migrated to pool $pool"
7385         echo "done."
7386
7387         echo -n "Removing test file from pool '$pool'..."
7388         # "lfs migrate $file" won't remove the file from the pool
7389         # until some striping information is changed.
7390         $LFS migrate -c 1 $file1 &> /dev/null ||
7391                 error "cannot remove from pool"
7392         [ "$($LFS getstripe -p $file1)" ] &&
7393                 error "pool still set"
7394         echo "done."
7395
7396         echo -n "Setting pool using --pool option..."
7397         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7398                 error "migrate failed rc = $?"
7399         echo "done."
7400
7401         # Clean up
7402         rm -f $file1
7403         if $create_pool; then
7404                 destroy_test_pools 2> /dev/null ||
7405                         error "destroy test pools failed"
7406         fi
7407 }
7408 run_test 56wb "check lfs_migrate pool support"
7409
7410 test_56wc() {
7411         local file1="$DIR/$tdir/file1"
7412         local parent_ssize
7413         local parent_scount
7414         local cur_ssize
7415         local cur_scount
7416         local orig_ssize
7417
7418         echo -n "Creating test dir..."
7419         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7420         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7421                 error "cannot set stripe by '-S 1M -c 1'"
7422         echo "done"
7423
7424         echo -n "Setting initial stripe for test file..."
7425         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7426                 error "cannot set stripe"
7427         cur_ssize=$($LFS getstripe -S "$file1")
7428         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7429         echo "done."
7430
7431         # File currently set to -S 512K -c 1
7432
7433         # Ensure -c and -S options are rejected when -R is set
7434         echo -n "Verifying incompatible options are detected..."
7435         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7436                 error "incompatible -c and -R options not detected"
7437         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7438                 error "incompatible -S and -R options not detected"
7439         echo "done."
7440
7441         # Ensure unrecognized options are passed through to 'lfs migrate'
7442         echo -n "Verifying -S option is passed through to lfs migrate..."
7443         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7444                 error "migration failed"
7445         cur_ssize=$($LFS getstripe -S "$file1")
7446         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7447         echo "done."
7448
7449         # File currently set to -S 1M -c 1
7450
7451         # Ensure long options are supported
7452         echo -n "Verifying long options supported..."
7453         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7454                 error "long option without argument not supported"
7455         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7456                 error "long option with argument not supported"
7457         cur_ssize=$($LFS getstripe -S "$file1")
7458         [ $cur_ssize -eq 524288 ] ||
7459                 error "migrate --stripe-size $cur_ssize != 524288"
7460         echo "done."
7461
7462         # File currently set to -S 512K -c 1
7463
7464         if [ "$OSTCOUNT" -gt 1 ]; then
7465                 echo -n "Verifying explicit stripe count can be set..."
7466                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7467                         error "migrate failed"
7468                 cur_scount=$($LFS getstripe -c "$file1")
7469                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7470                 echo "done."
7471         fi
7472
7473         # File currently set to -S 512K -c 1 or -S 512K -c 2
7474
7475         # Ensure parent striping is used if -R is set, and no stripe
7476         # count or size is specified
7477         echo -n "Setting stripe for parent directory..."
7478         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7479                 error "cannot set stripe '-S 2M -c 1'"
7480         echo "done."
7481
7482         echo -n "Verifying restripe option uses parent stripe settings..."
7483         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7484         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7485         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7486                 error "migrate failed"
7487         cur_ssize=$($LFS getstripe -S "$file1")
7488         [ $cur_ssize -eq $parent_ssize ] ||
7489                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7490         cur_scount=$($LFS getstripe -c "$file1")
7491         [ $cur_scount -eq $parent_scount ] ||
7492                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7493         echo "done."
7494
7495         # File currently set to -S 1M -c 1
7496
7497         # Ensure striping is preserved if -R is not set, and no stripe
7498         # count or size is specified
7499         echo -n "Verifying striping size preserved when not specified..."
7500         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7501         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7502                 error "cannot set stripe on parent directory"
7503         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7504                 error "migrate failed"
7505         cur_ssize=$($LFS getstripe -S "$file1")
7506         [ $cur_ssize -eq $orig_ssize ] ||
7507                 error "migrate by default $cur_ssize != $orig_ssize"
7508         echo "done."
7509
7510         # Ensure file name properly detected when final option has no argument
7511         echo -n "Verifying file name properly detected..."
7512         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7513                 error "file name interpreted as option argument"
7514         echo "done."
7515
7516         # Clean up
7517         rm -f "$file1"
7518 }
7519 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7520
7521 test_56wd() {
7522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7523
7524         local file1=$DIR/$tdir/file1
7525
7526         echo -n "Creating test dir..."
7527         test_mkdir $DIR/$tdir || error "cannot create dir"
7528         echo "done."
7529
7530         echo -n "Creating test file..."
7531         touch $file1
7532         echo "done."
7533
7534         # Ensure 'lfs migrate' will fail by using a non-existent option,
7535         # and make sure rsync is not called to recover
7536         echo -n "Make sure --no-rsync option works..."
7537         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7538                 grep -q 'refusing to fall back to rsync' ||
7539                 error "rsync was called with --no-rsync set"
7540         echo "done."
7541
7542         # Ensure rsync is called without trying 'lfs migrate' first
7543         echo -n "Make sure --rsync option works..."
7544         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7545                 grep -q 'falling back to rsync' &&
7546                 error "lfs migrate was called with --rsync set"
7547         echo "done."
7548
7549         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7550         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7551                 grep -q 'at the same time' ||
7552                 error "--rsync and --no-rsync accepted concurrently"
7553         echo "done."
7554
7555         # Clean up
7556         rm -f $file1
7557 }
7558 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7559
7560 test_56we() {
7561         local td=$DIR/$tdir
7562         local tf=$td/$tfile
7563
7564         test_mkdir $td || error "cannot create $td"
7565         touch $tf || error "cannot touch $tf"
7566
7567         echo -n "Make sure --non-direct|-D works..."
7568         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7569                 grep -q "lfs migrate --non-direct" ||
7570                 error "--non-direct option cannot work correctly"
7571         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7572                 grep -q "lfs migrate -D" ||
7573                 error "-D option cannot work correctly"
7574         echo "done."
7575 }
7576 run_test 56we "check lfs_migrate --non-direct|-D support"
7577
7578 test_56x() {
7579         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7580         check_swap_layouts_support
7581
7582         local dir=$DIR/$tdir
7583         local ref1=/etc/passwd
7584         local file1=$dir/file1
7585
7586         test_mkdir $dir || error "creating dir $dir"
7587         $LFS setstripe -c 2 $file1
7588         cp $ref1 $file1
7589         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7590         stripe=$($LFS getstripe -c $file1)
7591         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7592         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7593
7594         # clean up
7595         rm -f $file1
7596 }
7597 run_test 56x "lfs migration support"
7598
7599 test_56xa() {
7600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7601         check_swap_layouts_support
7602
7603         local dir=$DIR/$tdir/$testnum
7604
7605         test_mkdir -p $dir
7606
7607         local ref1=/etc/passwd
7608         local file1=$dir/file1
7609
7610         $LFS setstripe -c 2 $file1
7611         cp $ref1 $file1
7612         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7613
7614         local stripe=$($LFS getstripe -c $file1)
7615
7616         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7617         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7618
7619         # clean up
7620         rm -f $file1
7621 }
7622 run_test 56xa "lfs migration --block support"
7623
7624 check_migrate_links() {
7625         local dir="$1"
7626         local file1="$dir/file1"
7627         local begin="$2"
7628         local count="$3"
7629         local runas="$4"
7630         local total_count=$(($begin + $count - 1))
7631         local symlink_count=10
7632         local uniq_count=10
7633
7634         if [ ! -f "$file1" ]; then
7635                 echo -n "creating initial file..."
7636                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7637                         error "cannot setstripe initial file"
7638                 echo "done"
7639
7640                 echo -n "creating symlinks..."
7641                 for s in $(seq 1 $symlink_count); do
7642                         ln -s "$file1" "$dir/slink$s" ||
7643                                 error "cannot create symlinks"
7644                 done
7645                 echo "done"
7646
7647                 echo -n "creating nonlinked files..."
7648                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7649                         error "cannot create nonlinked files"
7650                 echo "done"
7651         fi
7652
7653         # create hard links
7654         if [ ! -f "$dir/file$total_count" ]; then
7655                 echo -n "creating hard links $begin:$total_count..."
7656                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7657                         /dev/null || error "cannot create hard links"
7658                 echo "done"
7659         fi
7660
7661         echo -n "checking number of hard links listed in xattrs..."
7662         local fid=$($LFS getstripe -F "$file1")
7663         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7664
7665         echo "${#paths[*]}"
7666         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7667                         skip "hard link list has unexpected size, skipping test"
7668         fi
7669         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7670                         error "link names should exceed xattrs size"
7671         fi
7672
7673         echo -n "migrating files..."
7674         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7675         local rc=$?
7676         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7677         echo "done"
7678
7679         # make sure all links have been properly migrated
7680         echo -n "verifying files..."
7681         fid=$($LFS getstripe -F "$file1") ||
7682                 error "cannot get fid for file $file1"
7683         for i in $(seq 2 $total_count); do
7684                 local fid2=$($LFS getstripe -F $dir/file$i)
7685
7686                 [ "$fid2" == "$fid" ] ||
7687                         error "migrated hard link has mismatched FID"
7688         done
7689
7690         # make sure hard links were properly detected, and migration was
7691         # performed only once for the entire link set; nonlinked files should
7692         # also be migrated
7693         local actual=$(grep -c 'done' <<< "$migrate_out")
7694         local expected=$(($uniq_count + 1))
7695
7696         [ "$actual" -eq  "$expected" ] ||
7697                 error "hard links individually migrated ($actual != $expected)"
7698
7699         # make sure the correct number of hard links are present
7700         local hardlinks=$(stat -c '%h' "$file1")
7701
7702         [ $hardlinks -eq $total_count ] ||
7703                 error "num hard links $hardlinks != $total_count"
7704         echo "done"
7705
7706         return 0
7707 }
7708
7709 test_56xb() {
7710         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7711                 skip "Need MDS version at least 2.10.55"
7712
7713         local dir="$DIR/$tdir"
7714
7715         test_mkdir "$dir" || error "cannot create dir $dir"
7716
7717         echo "testing lfs migrate mode when all links fit within xattrs"
7718         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7719
7720         echo "testing rsync mode when all links fit within xattrs"
7721         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7722
7723         echo "testing lfs migrate mode when all links do not fit within xattrs"
7724         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7725
7726         echo "testing rsync mode when all links do not fit within xattrs"
7727         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7728
7729         chown -R $RUNAS_ID $dir
7730         echo "testing non-root lfs migrate mode when not all links are in xattr"
7731         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7732
7733         # clean up
7734         rm -rf $dir
7735 }
7736 run_test 56xb "lfs migration hard link support"
7737
7738 test_56xc() {
7739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7740
7741         local dir="$DIR/$tdir"
7742
7743         test_mkdir "$dir" || error "cannot create dir $dir"
7744
7745         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7746         echo -n "Setting initial stripe for 20MB test file..."
7747         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7748                 error "cannot setstripe 20MB file"
7749         echo "done"
7750         echo -n "Sizing 20MB test file..."
7751         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7752         echo "done"
7753         echo -n "Verifying small file autostripe count is 1..."
7754         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7755                 error "cannot migrate 20MB file"
7756         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7757                 error "cannot get stripe for $dir/20mb"
7758         [ $stripe_count -eq 1 ] ||
7759                 error "unexpected stripe count $stripe_count for 20MB file"
7760         rm -f "$dir/20mb"
7761         echo "done"
7762
7763         # Test 2: File is small enough to fit within the available space on
7764         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7765         # have at least an additional 1KB for each desired stripe for test 3
7766         echo -n "Setting stripe for 1GB test file..."
7767         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7768         echo "done"
7769         echo -n "Sizing 1GB test file..."
7770         # File size is 1GB + 3KB
7771         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7772         echo "done"
7773
7774         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7775         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7776         if (( avail > 524288 * OSTCOUNT )); then
7777                 echo -n "Migrating 1GB file..."
7778                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7779                         error "cannot migrate 1GB file"
7780                 echo "done"
7781                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7782                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7783                         error "cannot getstripe for 1GB file"
7784                 [ $stripe_count -eq 2 ] ||
7785                         error "unexpected stripe count $stripe_count != 2"
7786                 echo "done"
7787         fi
7788
7789         # Test 3: File is too large to fit within the available space on
7790         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7791         if [ $OSTCOUNT -ge 3 ]; then
7792                 # The required available space is calculated as
7793                 # file size (1GB + 3KB) / OST count (3).
7794                 local kb_per_ost=349526
7795
7796                 echo -n "Migrating 1GB file with limit..."
7797                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7798                         error "cannot migrate 1GB file with limit"
7799                 echo "done"
7800
7801                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7802                 echo -n "Verifying 1GB autostripe count with limited space..."
7803                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7804                         error "unexpected stripe count $stripe_count (min 3)"
7805                 echo "done"
7806         fi
7807
7808         # clean up
7809         rm -rf $dir
7810 }
7811 run_test 56xc "lfs migration autostripe"
7812
7813 test_56xd() {
7814         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7815
7816         local dir=$DIR/$tdir
7817         local f_mgrt=$dir/$tfile.mgrt
7818         local f_yaml=$dir/$tfile.yaml
7819         local f_copy=$dir/$tfile.copy
7820         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7821         local layout_copy="-c 2 -S 2M -i 1"
7822         local yamlfile=$dir/yamlfile
7823         local layout_before;
7824         local layout_after;
7825
7826         test_mkdir "$dir" || error "cannot create dir $dir"
7827         $LFS setstripe $layout_yaml $f_yaml ||
7828                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7829         $LFS getstripe --yaml $f_yaml > $yamlfile
7830         $LFS setstripe $layout_copy $f_copy ||
7831                 error "cannot setstripe $f_copy with layout $layout_copy"
7832         touch $f_mgrt
7833         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7834
7835         # 1. test option --yaml
7836         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7837                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7838         layout_before=$(get_layout_param $f_yaml)
7839         layout_after=$(get_layout_param $f_mgrt)
7840         [ "$layout_after" == "$layout_before" ] ||
7841                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7842
7843         # 2. test option --copy
7844         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7845                 error "cannot migrate $f_mgrt with --copy $f_copy"
7846         layout_before=$(get_layout_param $f_copy)
7847         layout_after=$(get_layout_param $f_mgrt)
7848         [ "$layout_after" == "$layout_before" ] ||
7849                 error "lfs_migrate --copy: $layout_after != $layout_before"
7850 }
7851 run_test 56xd "check lfs_migrate --yaml and --copy support"
7852
7853 test_56xe() {
7854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7855
7856         local dir=$DIR/$tdir
7857         local f_comp=$dir/$tfile
7858         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7859         local layout_before=""
7860         local layout_after=""
7861
7862         test_mkdir "$dir" || error "cannot create dir $dir"
7863         $LFS setstripe $layout $f_comp ||
7864                 error "cannot setstripe $f_comp with layout $layout"
7865         layout_before=$(get_layout_param $f_comp)
7866         dd if=/dev/zero of=$f_comp bs=1M count=4
7867
7868         # 1. migrate a comp layout file by lfs_migrate
7869         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7870         layout_after=$(get_layout_param $f_comp)
7871         [ "$layout_before" == "$layout_after" ] ||
7872                 error "lfs_migrate: $layout_before != $layout_after"
7873
7874         # 2. migrate a comp layout file by lfs migrate
7875         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7876         layout_after=$(get_layout_param $f_comp)
7877         [ "$layout_before" == "$layout_after" ] ||
7878                 error "lfs migrate: $layout_before != $layout_after"
7879 }
7880 run_test 56xe "migrate a composite layout file"
7881
7882 test_56xf() {
7883         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7884
7885         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7886                 skip "Need server version at least 2.13.53"
7887
7888         local dir=$DIR/$tdir
7889         local f_comp=$dir/$tfile
7890         local layout="-E 1M -c1 -E -1 -c2"
7891         local fid_before=""
7892         local fid_after=""
7893
7894         test_mkdir "$dir" || error "cannot create dir $dir"
7895         $LFS setstripe $layout $f_comp ||
7896                 error "cannot setstripe $f_comp with layout $layout"
7897         fid_before=$($LFS getstripe --fid $f_comp)
7898         dd if=/dev/zero of=$f_comp bs=1M count=4
7899
7900         # 1. migrate a comp layout file to a comp layout
7901         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7902         fid_after=$($LFS getstripe --fid $f_comp)
7903         [ "$fid_before" == "$fid_after" ] ||
7904                 error "comp-to-comp migrate: $fid_before != $fid_after"
7905
7906         # 2. migrate a comp layout file to a plain layout
7907         $LFS migrate -c2 $f_comp ||
7908                 error "cannot migrate $f_comp by lfs migrate"
7909         fid_after=$($LFS getstripe --fid $f_comp)
7910         [ "$fid_before" == "$fid_after" ] ||
7911                 error "comp-to-plain migrate: $fid_before != $fid_after"
7912
7913         # 3. migrate a plain layout file to a comp layout
7914         $LFS migrate $layout $f_comp ||
7915                 error "cannot migrate $f_comp by lfs migrate"
7916         fid_after=$($LFS getstripe --fid $f_comp)
7917         [ "$fid_before" == "$fid_after" ] ||
7918                 error "plain-to-comp migrate: $fid_before != $fid_after"
7919 }
7920 run_test 56xf "FID is not lost during migration of a composite layout file"
7921
7922 check_file_ost_range() {
7923         local file="$1"
7924         shift
7925         local range="$*"
7926         local -a file_range
7927         local idx
7928
7929         file_range=($($LFS getstripe -y "$file" |
7930                 awk '/l_ost_idx:/ { print $NF }'))
7931
7932         if [[ "${#file_range[@]}" = 0 ]]; then
7933                 echo "No osts found for $file"
7934                 return 1
7935         fi
7936
7937         for idx in "${file_range[@]}"; do
7938                 [[ " $range " =~ " $idx " ]] ||
7939                         return 1
7940         done
7941
7942         return 0
7943 }
7944
7945 sub_test_56xg() {
7946         local stripe_opt="$1"
7947         local pool="$2"
7948         shift 2
7949         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7950
7951         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7952                 error "Fail to migrate $tfile on $pool"
7953         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7954                 error "$tfile is not in pool $pool"
7955         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7956                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7957 }
7958
7959 test_56xg() {
7960         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7961         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7962         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7963                 skip "Need MDS version newer than 2.14.52"
7964
7965         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7966         local -a pool_ranges=("0 0" "1 1" "0 1")
7967
7968         # init pools
7969         for i in "${!pool_names[@]}"; do
7970                 pool_add ${pool_names[$i]} ||
7971                         error "pool_add failed (pool: ${pool_names[$i]})"
7972                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7973                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7974         done
7975
7976         # init the file to migrate
7977         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7978                 error "Unable to create $tfile on OST1"
7979         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7980                 error "Unable to write on $tfile"
7981
7982         echo "1. migrate $tfile on pool ${pool_names[0]}"
7983         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7984
7985         echo "2. migrate $tfile on pool ${pool_names[2]}"
7986         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7987
7988         echo "3. migrate $tfile on pool ${pool_names[1]}"
7989         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7990
7991         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7992         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7993         echo
7994
7995         # Clean pools
7996         destroy_test_pools ||
7997                 error "pool_destroy failed"
7998 }
7999 run_test 56xg "lfs migrate pool support"
8000
8001 test_56y() {
8002         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8003                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8004
8005         local res=""
8006         local dir=$DIR/$tdir
8007         local f1=$dir/file1
8008         local f2=$dir/file2
8009
8010         test_mkdir -p $dir || error "creating dir $dir"
8011         touch $f1 || error "creating std file $f1"
8012         $MULTIOP $f2 H2c || error "creating released file $f2"
8013
8014         # a directory can be raid0, so ask only for files
8015         res=$($LFS find $dir -L raid0 -type f | wc -l)
8016         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8017
8018         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8019         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8020
8021         # only files can be released, so no need to force file search
8022         res=$($LFS find $dir -L released)
8023         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8024
8025         res=$($LFS find $dir -type f \! -L released)
8026         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8027 }
8028 run_test 56y "lfs find -L raid0|released"
8029
8030 test_56z() { # LU-4824
8031         # This checks to make sure 'lfs find' continues after errors
8032         # There are two classes of errors that should be caught:
8033         # - If multiple paths are provided, all should be searched even if one
8034         #   errors out
8035         # - If errors are encountered during the search, it should not terminate
8036         #   early
8037         local dir=$DIR/$tdir
8038         local i
8039
8040         test_mkdir $dir
8041         for i in d{0..9}; do
8042                 test_mkdir $dir/$i
8043                 touch $dir/$i/$tfile
8044         done
8045         $LFS find $DIR/non_existent_dir $dir &&
8046                 error "$LFS find did not return an error"
8047         # Make a directory unsearchable. This should NOT be the last entry in
8048         # directory order.  Arbitrarily pick the 6th entry
8049         chmod 700 $($LFS find $dir -type d | sed '6!d')
8050
8051         $RUNAS $LFS find $DIR/non_existent $dir
8052         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8053
8054         # The user should be able to see 10 directories and 9 files
8055         (( count == 19 )) ||
8056                 error "$LFS find found $count != 19 entries after error"
8057 }
8058 run_test 56z "lfs find should continue after an error"
8059
8060 test_56aa() { # LU-5937
8061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8062
8063         local dir=$DIR/$tdir
8064
8065         mkdir $dir
8066         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8067
8068         createmany -o $dir/striped_dir/${tfile}- 1024
8069         local dirs=$($LFS find --size +8k $dir/)
8070
8071         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8072 }
8073 run_test 56aa "lfs find --size under striped dir"
8074
8075 test_56ab() { # LU-10705
8076         test_mkdir $DIR/$tdir
8077         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8078         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8079         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8080         # Flush writes to ensure valid blocks.  Need to be more thorough for
8081         # ZFS, since blocks are not allocated/returned to client immediately.
8082         sync_all_data
8083         wait_zfs_commit ost1 2
8084         cancel_lru_locks osc
8085         ls -ls $DIR/$tdir
8086
8087         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8088
8089         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8090
8091         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8092         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8093
8094         rm -f $DIR/$tdir/$tfile.[123]
8095 }
8096 run_test 56ab "lfs find --blocks"
8097
8098 # LU-11188
8099 test_56aca() {
8100         local dir="$DIR/$tdir"
8101         local perms=(001 002 003 004 005 006 007
8102                      010 020 030 040 050 060 070
8103                      100 200 300 400 500 600 700
8104                      111 222 333 444 555 666 777)
8105         local perm_minus=(8 8 4 8 4 4 2
8106                           8 8 4 8 4 4 2
8107                           8 8 4 8 4 4 2
8108                           4 4 2 4 2 2 1)
8109         local perm_slash=(8  8 12  8 12 12 14
8110                           8  8 12  8 12 12 14
8111                           8  8 12  8 12 12 14
8112                          16 16 24 16 24 24 28)
8113
8114         test_mkdir "$dir"
8115         for perm in ${perms[*]}; do
8116                 touch "$dir/$tfile.$perm"
8117                 chmod $perm "$dir/$tfile.$perm"
8118         done
8119
8120         for ((i = 0; i < ${#perms[*]}; i++)); do
8121                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8122                 (( $num == 1 )) ||
8123                         error "lfs find -perm ${perms[i]}:"\
8124                               "$num != 1"
8125
8126                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8127                 (( $num == ${perm_minus[i]} )) ||
8128                         error "lfs find -perm -${perms[i]}:"\
8129                               "$num != ${perm_minus[i]}"
8130
8131                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8132                 (( $num == ${perm_slash[i]} )) ||
8133                         error "lfs find -perm /${perms[i]}:"\
8134                               "$num != ${perm_slash[i]}"
8135         done
8136 }
8137 run_test 56aca "check lfs find -perm with octal representation"
8138
8139 test_56acb() {
8140         local dir=$DIR/$tdir
8141         # p is the permission of write and execute for user, group and other
8142         # without the umask. It is used to test +wx.
8143         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8144         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8145         local symbolic=(+t  a+t u+t g+t o+t
8146                         g+s u+s o+s +s o+sr
8147                         o=r,ug+o,u+w
8148                         u+ g+ o+ a+ ugo+
8149                         u- g- o- a- ugo-
8150                         u= g= o= a= ugo=
8151                         o=r,ug+o,u+w u=r,a+u,u+w
8152                         g=r,ugo=g,u+w u+x,+X +X
8153                         u+x,u+X u+X u+x,g+X o+r,+X
8154                         u+x,go+X +wx +rwx)
8155
8156         test_mkdir $dir
8157         for perm in ${perms[*]}; do
8158                 touch "$dir/$tfile.$perm"
8159                 chmod $perm "$dir/$tfile.$perm"
8160         done
8161
8162         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8163                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8164
8165                 (( $num == 1 )) ||
8166                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8167         done
8168 }
8169 run_test 56acb "check lfs find -perm with symbolic representation"
8170
8171 test_56acc() {
8172         local dir=$DIR/$tdir
8173         local tests="17777 787 789 abcd
8174                 ug=uu ug=a ug=gu uo=ou urw
8175                 u+xg+x a=r,u+x,"
8176
8177         test_mkdir $dir
8178         for err in $tests; do
8179                 if $LFS find $dir -perm $err 2>/dev/null; then
8180                         error "lfs find -perm $err: parsing should have failed"
8181                 fi
8182         done
8183 }
8184 run_test 56acc "check parsing error for lfs find -perm"
8185
8186 test_56ba() {
8187         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8188                 skip "Need MDS version at least 2.10.50"
8189
8190         # Create composite files with one component
8191         local dir=$DIR/$tdir
8192
8193         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8194         # Create composite files with three components
8195         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8196         # Create non-composite files
8197         createmany -o $dir/${tfile}- 10
8198
8199         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8200
8201         [[ $nfiles == 10 ]] ||
8202                 error "lfs find -E 1M found $nfiles != 10 files"
8203
8204         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8205         [[ $nfiles == 25 ]] ||
8206                 error "lfs find ! -E 1M found $nfiles != 25 files"
8207
8208         # All files have a component that starts at 0
8209         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8210         [[ $nfiles == 35 ]] ||
8211                 error "lfs find --component-start 0 - $nfiles != 35 files"
8212
8213         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8214         [[ $nfiles == 15 ]] ||
8215                 error "lfs find --component-start 2M - $nfiles != 15 files"
8216
8217         # All files created here have a componenet that does not starts at 2M
8218         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8219         [[ $nfiles == 35 ]] ||
8220                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8221
8222         # Find files with a specified number of components
8223         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8224         [[ $nfiles == 15 ]] ||
8225                 error "lfs find --component-count 3 - $nfiles != 15 files"
8226
8227         # Remember non-composite files have a component count of zero
8228         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8229         [[ $nfiles == 10 ]] ||
8230                 error "lfs find --component-count 0 - $nfiles != 10 files"
8231
8232         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8233         [[ $nfiles == 20 ]] ||
8234                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8235
8236         # All files have a flag called "init"
8237         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8238         [[ $nfiles == 35 ]] ||
8239                 error "lfs find --component-flags init - $nfiles != 35 files"
8240
8241         # Multi-component files will have a component not initialized
8242         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8243         [[ $nfiles == 15 ]] ||
8244                 error "lfs find !--component-flags init - $nfiles != 15 files"
8245
8246         rm -rf $dir
8247
8248 }
8249 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8250
8251 test_56ca() {
8252         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8253                 skip "Need MDS version at least 2.10.57"
8254
8255         local td=$DIR/$tdir
8256         local tf=$td/$tfile
8257         local dir
8258         local nfiles
8259         local cmd
8260         local i
8261         local j
8262
8263         # create mirrored directories and mirrored files
8264         mkdir $td || error "mkdir $td failed"
8265         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8266         createmany -o $tf- 10 || error "create $tf- failed"
8267
8268         for i in $(seq 2); do
8269                 dir=$td/dir$i
8270                 mkdir $dir || error "mkdir $dir failed"
8271                 $LFS mirror create -N$((3 + i)) $dir ||
8272                         error "create mirrored dir $dir failed"
8273                 createmany -o $dir/$tfile- 10 ||
8274                         error "create $dir/$tfile- failed"
8275         done
8276
8277         # change the states of some mirrored files
8278         echo foo > $tf-6
8279         for i in $(seq 2); do
8280                 dir=$td/dir$i
8281                 for j in $(seq 4 9); do
8282                         echo foo > $dir/$tfile-$j
8283                 done
8284         done
8285
8286         # find mirrored files with specific mirror count
8287         cmd="$LFS find --mirror-count 3 --type f $td"
8288         nfiles=$($cmd | wc -l)
8289         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8290
8291         cmd="$LFS find ! --mirror-count 3 --type f $td"
8292         nfiles=$($cmd | wc -l)
8293         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8294
8295         cmd="$LFS find --mirror-count +2 --type f $td"
8296         nfiles=$($cmd | wc -l)
8297         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8298
8299         cmd="$LFS find --mirror-count -6 --type f $td"
8300         nfiles=$($cmd | wc -l)
8301         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8302
8303         # find mirrored files with specific file state
8304         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8305         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8306
8307         cmd="$LFS find --mirror-state=ro --type f $td"
8308         nfiles=$($cmd | wc -l)
8309         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8310
8311         cmd="$LFS find ! --mirror-state=ro --type f $td"
8312         nfiles=$($cmd | wc -l)
8313         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8314
8315         cmd="$LFS find --mirror-state=wp --type f $td"
8316         nfiles=$($cmd | wc -l)
8317         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8318
8319         cmd="$LFS find ! --mirror-state=sp --type f $td"
8320         nfiles=$($cmd | wc -l)
8321         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8322 }
8323 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8324
8325 test_56da() { # LU-14179
8326         local path=$DIR/$tdir
8327
8328         test_mkdir $path
8329         cd $path
8330
8331         local longdir=$(str_repeat 'a' 255)
8332
8333         for i in {1..15}; do
8334                 path=$path/$longdir
8335                 test_mkdir $longdir
8336                 cd $longdir
8337         done
8338
8339         local len=${#path}
8340         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8341
8342         test_mkdir $lastdir
8343         cd $lastdir
8344         # PATH_MAX-1
8345         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8346
8347         # NAME_MAX
8348         touch $(str_repeat 'f' 255)
8349
8350         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8351                 error "lfs find reported an error"
8352
8353         rm -rf $DIR/$tdir
8354 }
8355 run_test 56da "test lfs find with long paths"
8356
8357 test_56ea() { #LU-10378
8358         local path=$DIR/$tdir
8359         local pool=$TESTNAME
8360
8361         # Create ost pool
8362         pool_add $pool || error "pool_add $pool failed"
8363         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8364                 error "adding targets to $pool failed"
8365
8366         # Set default pool on directory before creating file
8367         mkdir $path || error "mkdir $path failed"
8368         $LFS setstripe -p $pool $path ||
8369                 error "set OST pool on $pool failed"
8370         touch $path/$tfile || error "touch $path/$tfile failed"
8371
8372         # Compare basic file attributes from -printf and stat
8373         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8374         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8375
8376         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8377                 error "Attrs from lfs find and stat don't match"
8378
8379         # Compare Lustre attributes from lfs find and lfs getstripe
8380         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8381         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8382         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8383         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8384         local fpool=$($LFS getstripe --pool $path/$tfile)
8385         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8386
8387         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8388                 error "Attrs from lfs find and lfs getstripe don't match"
8389
8390         # Verify behavior for unknown escape/format sequences
8391         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8392
8393         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8394                 error "Escape/format codes don't match"
8395 }
8396 run_test 56ea "test lfs find -printf option"
8397
8398 test_57a() {
8399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8400         # note test will not do anything if MDS is not local
8401         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8402                 skip_env "ldiskfs only test"
8403         fi
8404         remote_mds_nodsh && skip "remote MDS with nodsh"
8405
8406         local MNTDEV="osd*.*MDT*.mntdev"
8407         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8408         [ -z "$DEV" ] && error "can't access $MNTDEV"
8409         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8410                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8411                         error "can't access $DEV"
8412                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8413                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8414                 rm $TMP/t57a.dump
8415         done
8416 }
8417 run_test 57a "verify MDS filesystem created with large inodes =="
8418
8419 test_57b() {
8420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8421         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8422                 skip_env "ldiskfs only test"
8423         fi
8424         remote_mds_nodsh && skip "remote MDS with nodsh"
8425
8426         local dir=$DIR/$tdir
8427         local filecount=100
8428         local file1=$dir/f1
8429         local fileN=$dir/f$filecount
8430
8431         rm -rf $dir || error "removing $dir"
8432         test_mkdir -c1 $dir
8433         local mdtidx=$($LFS getstripe -m $dir)
8434         local mdtname=MDT$(printf %04x $mdtidx)
8435         local facet=mds$((mdtidx + 1))
8436
8437         echo "mcreating $filecount files"
8438         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8439
8440         # verify that files do not have EAs yet
8441         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8442                 error "$file1 has an EA"
8443         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8444                 error "$fileN has an EA"
8445
8446         sync
8447         sleep 1
8448         df $dir  #make sure we get new statfs data
8449         local mdsfree=$(do_facet $facet \
8450                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8451         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8452         local file
8453
8454         echo "opening files to create objects/EAs"
8455         for file in $(seq -f $dir/f%g 1 $filecount); do
8456                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8457                         error "opening $file"
8458         done
8459
8460         # verify that files have EAs now
8461         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8462         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8463
8464         sleep 1  #make sure we get new statfs data
8465         df $dir
8466         local mdsfree2=$(do_facet $facet \
8467                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8468         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8469
8470         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8471                 if [ "$mdsfree" != "$mdsfree2" ]; then
8472                         error "MDC before $mdcfree != after $mdcfree2"
8473                 else
8474                         echo "MDC before $mdcfree != after $mdcfree2"
8475                         echo "unable to confirm if MDS has large inodes"
8476                 fi
8477         fi
8478         rm -rf $dir
8479 }
8480 run_test 57b "default LOV EAs are stored inside large inodes ==="
8481
8482 test_58() {
8483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8484         [ -z "$(which wiretest 2>/dev/null)" ] &&
8485                         skip_env "could not find wiretest"
8486
8487         wiretest
8488 }
8489 run_test 58 "verify cross-platform wire constants =============="
8490
8491 test_59() {
8492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8493
8494         echo "touch 130 files"
8495         createmany -o $DIR/f59- 130
8496         echo "rm 130 files"
8497         unlinkmany $DIR/f59- 130
8498         sync
8499         # wait for commitment of removal
8500         wait_delete_completed
8501 }
8502 run_test 59 "verify cancellation of llog records async ========="
8503
8504 TEST60_HEAD="test_60 run $RANDOM"
8505 test_60a() {
8506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8507         remote_mgs_nodsh && skip "remote MGS with nodsh"
8508         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8509                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8510                         skip_env "missing subtest run-llog.sh"
8511
8512         log "$TEST60_HEAD - from kernel mode"
8513         do_facet mgs "$LCTL dk > /dev/null"
8514         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8515         do_facet mgs $LCTL dk > $TMP/$tfile
8516
8517         # LU-6388: test llog_reader
8518         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8519         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8520         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8521                         skip_env "missing llog_reader"
8522         local fstype=$(facet_fstype mgs)
8523         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8524                 skip_env "Only for ldiskfs or zfs type mgs"
8525
8526         local mntpt=$(facet_mntpt mgs)
8527         local mgsdev=$(mgsdevname 1)
8528         local fid_list
8529         local fid
8530         local rec_list
8531         local rec
8532         local rec_type
8533         local obj_file
8534         local path
8535         local seq
8536         local oid
8537         local pass=true
8538
8539         #get fid and record list
8540         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8541                 tail -n 4))
8542         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8543                 tail -n 4))
8544         #remount mgs as ldiskfs or zfs type
8545         stop mgs || error "stop mgs failed"
8546         mount_fstype mgs || error "remount mgs failed"
8547         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8548                 fid=${fid_list[i]}
8549                 rec=${rec_list[i]}
8550                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8551                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8552                 oid=$((16#$oid))
8553
8554                 case $fstype in
8555                         ldiskfs )
8556                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8557                         zfs )
8558                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8559                 esac
8560                 echo "obj_file is $obj_file"
8561                 do_facet mgs $llog_reader $obj_file
8562
8563                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8564                         awk '{ print $3 }' | sed -e "s/^type=//g")
8565                 if [ $rec_type != $rec ]; then
8566                         echo "FAILED test_60a wrong record type $rec_type," \
8567                               "should be $rec"
8568                         pass=false
8569                         break
8570                 fi
8571
8572                 #check obj path if record type is LLOG_LOGID_MAGIC
8573                 if [ "$rec" == "1064553b" ]; then
8574                         path=$(do_facet mgs $llog_reader $obj_file |
8575                                 grep "path=" | awk '{ print $NF }' |
8576                                 sed -e "s/^path=//g")
8577                         if [ $obj_file != $mntpt/$path ]; then
8578                                 echo "FAILED test_60a wrong obj path" \
8579                                       "$montpt/$path, should be $obj_file"
8580                                 pass=false
8581                                 break
8582                         fi
8583                 fi
8584         done
8585         rm -f $TMP/$tfile
8586         #restart mgs before "error", otherwise it will block the next test
8587         stop mgs || error "stop mgs failed"
8588         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8589         $pass || error "test failed, see FAILED test_60a messages for specifics"
8590 }
8591 run_test 60a "llog_test run from kernel module and test llog_reader"
8592
8593 test_60b() { # bug 6411
8594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8595
8596         dmesg > $DIR/$tfile
8597         LLOG_COUNT=$(do_facet mgs dmesg |
8598                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8599                           /llog_[a-z]*.c:[0-9]/ {
8600                                 if (marker)
8601                                         from_marker++
8602                                 from_begin++
8603                           }
8604                           END {
8605                                 if (marker)
8606                                         print from_marker
8607                                 else
8608                                         print from_begin
8609                           }")
8610
8611         [[ $LLOG_COUNT -gt 120 ]] &&
8612                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8613 }
8614 run_test 60b "limit repeated messages from CERROR/CWARN"
8615
8616 test_60c() {
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         echo "create 5000 files"
8620         createmany -o $DIR/f60c- 5000
8621 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8622         lctl set_param fail_loc=0x80000137
8623         unlinkmany $DIR/f60c- 5000
8624         lctl set_param fail_loc=0
8625 }
8626 run_test 60c "unlink file when mds full"
8627
8628 test_60d() {
8629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8630
8631         SAVEPRINTK=$(lctl get_param -n printk)
8632         # verify "lctl mark" is even working"
8633         MESSAGE="test message ID $RANDOM $$"
8634         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8635         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8636
8637         lctl set_param printk=0 || error "set lnet.printk failed"
8638         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8639         MESSAGE="new test message ID $RANDOM $$"
8640         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8641         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8642         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8643
8644         lctl set_param -n printk="$SAVEPRINTK"
8645 }
8646 run_test 60d "test printk console message masking"
8647
8648 test_60e() {
8649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8650         remote_mds_nodsh && skip "remote MDS with nodsh"
8651
8652         touch $DIR/$tfile
8653 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8654         do_facet mds1 lctl set_param fail_loc=0x15b
8655         rm $DIR/$tfile
8656 }
8657 run_test 60e "no space while new llog is being created"
8658
8659 test_60f() {
8660         local old_path=$($LCTL get_param -n debug_path)
8661
8662         stack_trap "$LCTL set_param debug_path=$old_path"
8663         stack_trap "rm -f $TMP/$tfile*"
8664         rm -f $TMP/$tfile* 2> /dev/null
8665         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8666         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8667         test_mkdir $DIR/$tdir
8668         # retry in case the open is cached and not released
8669         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8670                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8671                 sleep 0.1
8672         done
8673         ls $TMP/$tfile*
8674         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8675 }
8676 run_test 60f "change debug_path works"
8677
8678 test_60g() {
8679         local pid
8680         local i
8681
8682         test_mkdir -c $MDSCOUNT $DIR/$tdir
8683
8684         (
8685                 local index=0
8686                 while true; do
8687                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8688                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8689                                 2>/dev/null
8690                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8691                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8692                         index=$((index + 1))
8693                 done
8694         ) &
8695
8696         pid=$!
8697
8698         for i in {0..100}; do
8699                 # define OBD_FAIL_OSD_TXN_START    0x19a
8700                 local index=$((i % MDSCOUNT + 1))
8701
8702                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8703                         > /dev/null
8704                 sleep 0.01
8705         done
8706
8707         kill -9 $pid
8708
8709         for i in $(seq $MDSCOUNT); do
8710                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8711         done
8712
8713         mkdir $DIR/$tdir/new || error "mkdir failed"
8714         rmdir $DIR/$tdir/new || error "rmdir failed"
8715
8716         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8717                 -t namespace
8718         for i in $(seq $MDSCOUNT); do
8719                 wait_update_facet mds$i "$LCTL get_param -n \
8720                         mdd.$(facet_svc mds$i).lfsck_namespace |
8721                         awk '/^status/ { print \\\$2 }'" "completed"
8722         done
8723
8724         ls -R $DIR/$tdir
8725         rm -rf $DIR/$tdir || error "rmdir failed"
8726 }
8727 run_test 60g "transaction abort won't cause MDT hung"
8728
8729 test_60h() {
8730         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8731                 skip "Need MDS version at least 2.12.52"
8732         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8733
8734         local f
8735
8736         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8737         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8738         for fail_loc in 0x80000188 0x80000189; do
8739                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8740                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8741                         error "mkdir $dir-$fail_loc failed"
8742                 for i in {0..10}; do
8743                         # create may fail on missing stripe
8744                         echo $i > $DIR/$tdir-$fail_loc/$i
8745                 done
8746                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8747                         error "getdirstripe $tdir-$fail_loc failed"
8748                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8749                         error "migrate $tdir-$fail_loc failed"
8750                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8751                         error "getdirstripe $tdir-$fail_loc failed"
8752                 pushd $DIR/$tdir-$fail_loc
8753                 for f in *; do
8754                         echo $f | cmp $f - || error "$f data mismatch"
8755                 done
8756                 popd
8757                 rm -rf $DIR/$tdir-$fail_loc
8758         done
8759 }
8760 run_test 60h "striped directory with missing stripes can be accessed"
8761
8762 function t60i_load() {
8763         mkdir $DIR/$tdir
8764         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8765         $LCTL set_param fail_loc=0x131c fail_val=1
8766         for ((i=0; i<5000; i++)); do
8767                 touch $DIR/$tdir/f$i
8768         done
8769 }
8770
8771 test_60i() {
8772         changelog_register || error "changelog_register failed"
8773         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8774         changelog_users $SINGLEMDS | grep -q $cl_user ||
8775                 error "User $cl_user not found in changelog_users"
8776         changelog_chmask "ALL"
8777         t60i_load &
8778         local PID=$!
8779         for((i=0; i<100; i++)); do
8780                 changelog_dump >/dev/null ||
8781                         error "can't read changelog"
8782         done
8783         kill $PID
8784         wait $PID
8785         changelog_deregister || error "changelog_deregister failed"
8786         $LCTL set_param fail_loc=0
8787 }
8788 run_test 60i "llog: new record vs reader race"
8789
8790 test_61a() {
8791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8792
8793         f="$DIR/f61"
8794         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8795         cancel_lru_locks osc
8796         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8797         sync
8798 }
8799 run_test 61a "mmap() writes don't make sync hang ================"
8800
8801 test_61b() {
8802         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8803 }
8804 run_test 61b "mmap() of unstriped file is successful"
8805
8806 # bug 2330 - insufficient obd_match error checking causes LBUG
8807 test_62() {
8808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8809
8810         f="$DIR/f62"
8811         echo foo > $f
8812         cancel_lru_locks osc
8813         lctl set_param fail_loc=0x405
8814         cat $f && error "cat succeeded, expect -EIO"
8815         lctl set_param fail_loc=0
8816 }
8817 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8818 # match every page all of the time.
8819 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8820
8821 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8822 # Though this test is irrelevant anymore, it helped to reveal some
8823 # other grant bugs (LU-4482), let's keep it.
8824 test_63a() {   # was test_63
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826
8827         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8828
8829         for i in `seq 10` ; do
8830                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8831                 sleep 5
8832                 kill $!
8833                 sleep 1
8834         done
8835
8836         rm -f $DIR/f63 || true
8837 }
8838 run_test 63a "Verify oig_wait interruption does not crash ======="
8839
8840 # bug 2248 - async write errors didn't return to application on sync
8841 # bug 3677 - async write errors left page locked
8842 test_63b() {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844
8845         debugsave
8846         lctl set_param debug=-1
8847
8848         # ensure we have a grant to do async writes
8849         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8850         rm $DIR/$tfile
8851
8852         sync    # sync lest earlier test intercept the fail_loc
8853
8854         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8855         lctl set_param fail_loc=0x80000406
8856         $MULTIOP $DIR/$tfile Owy && \
8857                 error "sync didn't return ENOMEM"
8858         sync; sleep 2; sync     # do a real sync this time to flush page
8859         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8860                 error "locked page left in cache after async error" || true
8861         debugrestore
8862 }
8863 run_test 63b "async write errors should be returned to fsync ==="
8864
8865 test_64a () {
8866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8867
8868         lfs df $DIR
8869         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8870 }
8871 run_test 64a "verify filter grant calculations (in kernel) ====="
8872
8873 test_64b () {
8874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8875
8876         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8877 }
8878 run_test 64b "check out-of-space detection on client"
8879
8880 test_64c() {
8881         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8882 }
8883 run_test 64c "verify grant shrink"
8884
8885 import_param() {
8886         local tgt=$1
8887         local param=$2
8888
8889         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8890 }
8891
8892 # this does exactly what osc_request.c:osc_announce_cached() does in
8893 # order to calculate max amount of grants to ask from server
8894 want_grant() {
8895         local tgt=$1
8896
8897         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8898         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8899
8900         ((rpc_in_flight++));
8901         nrpages=$((nrpages * rpc_in_flight))
8902
8903         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8904
8905         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8906
8907         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8908         local undirty=$((nrpages * PAGE_SIZE))
8909
8910         local max_extent_pages
8911         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8912         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8913         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8914         local grant_extent_tax
8915         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8916
8917         undirty=$((undirty + nrextents * grant_extent_tax))
8918
8919         echo $undirty
8920 }
8921
8922 # this is size of unit for grant allocation. It should be equal to
8923 # what tgt_grant.c:tgt_grant_chunk() calculates
8924 grant_chunk() {
8925         local tgt=$1
8926         local max_brw_size
8927         local grant_extent_tax
8928
8929         max_brw_size=$(import_param $tgt max_brw_size)
8930
8931         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8932
8933         echo $(((max_brw_size + grant_extent_tax) * 2))
8934 }
8935
8936 test_64d() {
8937         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8938                 skip "OST < 2.10.55 doesn't limit grants enough"
8939
8940         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8941
8942         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8943                 skip "no grant_param connect flag"
8944
8945         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8946
8947         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8948         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8949
8950
8951         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8952         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8953
8954         $LFS setstripe $DIR/$tfile -i 0 -c 1
8955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8956         ddpid=$!
8957
8958         while kill -0 $ddpid; do
8959                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8960
8961                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8962                         kill $ddpid
8963                         error "cur_grant $cur_grant > $max_cur_granted"
8964                 fi
8965
8966                 sleep 1
8967         done
8968 }
8969 run_test 64d "check grant limit exceed"
8970
8971 check_grants() {
8972         local tgt=$1
8973         local expected=$2
8974         local msg=$3
8975         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8976
8977         ((cur_grants == expected)) ||
8978                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8979 }
8980
8981 round_up_p2() {
8982         echo $((($1 + $2 - 1) & ~($2 - 1)))
8983 }
8984
8985 test_64e() {
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8988                 skip "Need OSS version at least 2.11.56"
8989
8990         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8991         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8992         $LCTL set_param debug=+cache
8993
8994         # Remount client to reset grant
8995         remount_client $MOUNT || error "failed to remount client"
8996         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8997
8998         local init_grants=$(import_param $osc_tgt initial_grant)
8999
9000         check_grants $osc_tgt $init_grants "init grants"
9001
9002         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9003         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9004         local gbs=$(import_param $osc_tgt grant_block_size)
9005
9006         # write random number of bytes from max_brw_size / 4 to max_brw_size
9007         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9008         # align for direct io
9009         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9010         # round to grant consumption unit
9011         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9012
9013         local grants=$((wb_round_up + extent_tax))
9014
9015         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9016
9017         # define OBD_FAIL_TGT_NO_GRANT 0x725
9018         # make the server not grant more back
9019         do_facet ost1 $LCTL set_param fail_loc=0x725
9020         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9021
9022         do_facet ost1 $LCTL set_param fail_loc=0
9023
9024         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9025
9026         rm -f $DIR/$tfile || error "rm failed"
9027
9028         # Remount client to reset grant
9029         remount_client $MOUNT || error "failed to remount client"
9030         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9031
9032         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9033
9034         # define OBD_FAIL_TGT_NO_GRANT 0x725
9035         # make the server not grant more back
9036         do_facet ost1 $LCTL set_param fail_loc=0x725
9037         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9038         do_facet ost1 $LCTL set_param fail_loc=0
9039
9040         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9041 }
9042 run_test 64e "check grant consumption (no grant allocation)"
9043
9044 test_64f() {
9045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9046
9047         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9048         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9049         $LCTL set_param debug=+cache
9050
9051         # Remount client to reset grant
9052         remount_client $MOUNT || error "failed to remount client"
9053         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9054
9055         local init_grants=$(import_param $osc_tgt initial_grant)
9056         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9057         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9058         local gbs=$(import_param $osc_tgt grant_block_size)
9059         local chunk=$(grant_chunk $osc_tgt)
9060
9061         # write random number of bytes from max_brw_size / 4 to max_brw_size
9062         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9063         # align for direct io
9064         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9065         # round to grant consumption unit
9066         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9067
9068         local grants=$((wb_round_up + extent_tax))
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9071         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9072                 error "error writing to $DIR/$tfile"
9073
9074         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9075                 "direct io with grant allocation"
9076
9077         rm -f $DIR/$tfile || error "rm failed"
9078
9079         # Remount client to reset grant
9080         remount_client $MOUNT || error "failed to remount client"
9081         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9082
9083         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9084
9085         local cmd="oO_WRONLY:w${write_bytes}_yc"
9086
9087         $MULTIOP $DIR/$tfile $cmd &
9088         MULTIPID=$!
9089         sleep 1
9090
9091         check_grants $osc_tgt $((init_grants - grants)) \
9092                 "buffered io, not write rpc"
9093
9094         kill -USR1 $MULTIPID
9095         wait
9096
9097         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9098                 "buffered io, one RPC"
9099 }
9100 run_test 64f "check grant consumption (with grant allocation)"
9101
9102 test_64g() {
9103         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9104                 skip "Need MDS version at least 2.14.56"
9105
9106         local mdts=$(comma_list $(mdts_nodes))
9107
9108         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9109                         tr '\n' ' ')
9110         stack_trap "$LCTL set_param $old"
9111
9112         # generate dirty pages and increase dirty granted on MDT
9113         stack_trap "rm -f $DIR/$tfile-*"
9114         for (( i = 0; i < 10; i++)); do
9115                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9116                         error "can't set stripe"
9117                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9118                         error "can't dd"
9119                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9120                         $LFS getstripe $DIR/$tfile-$i
9121                         error "not DoM file"
9122                 }
9123         done
9124
9125         # flush dirty pages
9126         sync
9127
9128         # wait until grant shrink reset grant dirty on MDTs
9129         for ((i = 0; i < 120; i++)); do
9130                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9131                         awk '{sum=sum+$1} END {print sum}')
9132                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9133                 echo "$grant_dirty grants, $vm_dirty pages"
9134                 (( grant_dirty + vm_dirty == 0 )) && break
9135                 (( i == 3 )) && sync &&
9136                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9137                 sleep 1
9138         done
9139
9140         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9141                 awk '{sum=sum+$1} END {print sum}')
9142         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9143 }
9144 run_test 64g "grant shrink on MDT"
9145
9146 test_64h() {
9147         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9148                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9149
9150         local instance=$($LFS getname -i $DIR)
9151         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9152         local num_exps=$(do_facet ost1 \
9153             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9154         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9155         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9157
9158         # 10MiB is for file to be written, max_brw_size * 16 *
9159         # num_exps is space reserve so that tgt_grant_shrink() decided
9160         # to not shrink
9161         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9162         (( avail * 1024 < expect )) &&
9163                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9164
9165         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9166         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9167         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9168         $LCTL set_param osc.*OST0000*.grant_shrink=1
9169         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9170
9171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9173
9174         # drop cache so that coming read would do rpc
9175         cancel_lru_locks osc
9176
9177         # shrink interval is set to 10, pause for 7 seconds so that
9178         # grant thread did not wake up yet but coming read entered
9179         # shrink mode for rpc (osc_should_shrink_grant())
9180         sleep 7
9181
9182         declare -a cur_grant_bytes
9183         declare -a tot_granted
9184         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9185         tot_granted[0]=$(do_facet ost1 \
9186             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9187
9188         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9189
9190         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9191         tot_granted[1]=$(do_facet ost1 \
9192             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9193
9194         # grant change should be equal on both sides
9195         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9196                 tot_granted[0] - tot_granted[1])) ||
9197                 error "grant change mismatch, "                                \
9198                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9199                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9200 }
9201 run_test 64h "grant shrink on read"
9202
9203 test_64i() {
9204         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9205                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9206
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208         remote_ost_nodsh && skip "remote OSTs with nodsh"
9209
9210         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9211
9212         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9213
9214         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9215         local instance=$($LFS getname -i $DIR)
9216
9217         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9218         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9219
9220         # shrink grants and simulate rpc loss
9221         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9222         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9223         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9224
9225         fail ost1
9226
9227         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9228
9229         local testid=$(echo $TESTNAME | tr '_' ' ')
9230
9231         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9232                 grep "GRANT, real grant" &&
9233                 error "client has more grants then it owns" || true
9234 }
9235 run_test 64i "shrink on reconnect"
9236
9237 # bug 1414 - set/get directories' stripe info
9238 test_65a() {
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240
9241         test_mkdir $DIR/$tdir
9242         touch $DIR/$tdir/f1
9243         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9244 }
9245 run_test 65a "directory with no stripe info"
9246
9247 test_65b() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249
9250         test_mkdir $DIR/$tdir
9251         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9252
9253         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9254                                                 error "setstripe"
9255         touch $DIR/$tdir/f2
9256         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9257 }
9258 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9259
9260 test_65c() {
9261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9262         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9263
9264         test_mkdir $DIR/$tdir
9265         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9266
9267         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9268                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9269         touch $DIR/$tdir/f3
9270         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9271 }
9272 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9273
9274 test_65d() {
9275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9276
9277         test_mkdir $DIR/$tdir
9278         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9279         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9280
9281         if [[ $STRIPECOUNT -le 0 ]]; then
9282                 sc=1
9283         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9284                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9285                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9286         else
9287                 sc=$(($STRIPECOUNT - 1))
9288         fi
9289         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9290         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9291         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9292                 error "lverify failed"
9293 }
9294 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9295
9296 test_65e() {
9297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9298
9299         test_mkdir $DIR/$tdir
9300
9301         $LFS setstripe $DIR/$tdir || error "setstripe"
9302         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9303                                         error "no stripe info failed"
9304         touch $DIR/$tdir/f6
9305         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9306 }
9307 run_test 65e "directory setstripe defaults"
9308
9309 test_65f() {
9310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9311
9312         test_mkdir $DIR/${tdir}f
9313         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9314                 error "setstripe succeeded" || true
9315 }
9316 run_test 65f "dir setstripe permission (should return error) ==="
9317
9318 test_65g() {
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320
9321         test_mkdir $DIR/$tdir
9322         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9323
9324         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9325                 error "setstripe -S failed"
9326         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9327         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9328                 error "delete default stripe failed"
9329 }
9330 run_test 65g "directory setstripe -d"
9331
9332 test_65h() {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334
9335         test_mkdir $DIR/$tdir
9336         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9337
9338         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9339                 error "setstripe -S failed"
9340         test_mkdir $DIR/$tdir/dd1
9341         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9342                 error "stripe info inherit failed"
9343 }
9344 run_test 65h "directory stripe info inherit ===================="
9345
9346 test_65i() {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348
9349         save_layout_restore_at_exit $MOUNT
9350
9351         # bug6367: set non-default striping on root directory
9352         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9353
9354         # bug12836: getstripe on -1 default directory striping
9355         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9356
9357         # bug12836: getstripe -v on -1 default directory striping
9358         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9359
9360         # bug12836: new find on -1 default directory striping
9361         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9362 }
9363 run_test 65i "various tests to set root directory striping"
9364
9365 test_65j() { # bug6367
9366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9367
9368         sync; sleep 1
9369
9370         # if we aren't already remounting for each test, do so for this test
9371         if [ "$I_MOUNTED" = "yes" ]; then
9372                 cleanup || error "failed to unmount"
9373                 setup
9374         fi
9375
9376         save_layout_restore_at_exit $MOUNT
9377
9378         $LFS setstripe -d $MOUNT || error "setstripe failed"
9379 }
9380 run_test 65j "set default striping on root directory (bug 6367)="
9381
9382 cleanup_65k() {
9383         rm -rf $DIR/$tdir
9384         wait_delete_completed
9385         do_facet $SINGLEMDS "lctl set_param -n \
9386                 osp.$ost*MDT0000.max_create_count=$max_count"
9387         do_facet $SINGLEMDS "lctl set_param -n \
9388                 osp.$ost*MDT0000.create_count=$count"
9389         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9390         echo $INACTIVE_OSC "is Activate"
9391
9392         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9393 }
9394
9395 test_65k() { # bug11679
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9398         remote_mds_nodsh && skip "remote MDS with nodsh"
9399
9400         local disable_precreate=true
9401         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9402                 disable_precreate=false
9403
9404         echo "Check OST status: "
9405         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9406                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9407
9408         for OSC in $MDS_OSCS; do
9409                 echo $OSC "is active"
9410                 do_facet $SINGLEMDS lctl --device %$OSC activate
9411         done
9412
9413         for INACTIVE_OSC in $MDS_OSCS; do
9414                 local ost=$(osc_to_ost $INACTIVE_OSC)
9415                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9416                                lov.*md*.target_obd |
9417                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9418
9419                 mkdir -p $DIR/$tdir
9420                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9421                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9422
9423                 echo "Deactivate: " $INACTIVE_OSC
9424                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9425
9426                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9427                               osp.$ost*MDT0000.create_count")
9428                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9429                                   osp.$ost*MDT0000.max_create_count")
9430                 $disable_precreate &&
9431                         do_facet $SINGLEMDS "lctl set_param -n \
9432                                 osp.$ost*MDT0000.max_create_count=0"
9433
9434                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9435                         [ -f $DIR/$tdir/$idx ] && continue
9436                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9437                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9438                                 { cleanup_65k;
9439                                   error "setstripe $idx should succeed"; }
9440                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9441                 done
9442                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9443                 rmdir $DIR/$tdir
9444
9445                 do_facet $SINGLEMDS "lctl set_param -n \
9446                         osp.$ost*MDT0000.max_create_count=$max_count"
9447                 do_facet $SINGLEMDS "lctl set_param -n \
9448                         osp.$ost*MDT0000.create_count=$count"
9449                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9450                 echo $INACTIVE_OSC "is Activate"
9451
9452                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9453         done
9454 }
9455 run_test 65k "validate manual striping works properly with deactivated OSCs"
9456
9457 test_65l() { # bug 12836
9458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9459
9460         test_mkdir -p $DIR/$tdir/test_dir
9461         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9462         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9463 }
9464 run_test 65l "lfs find on -1 stripe dir ========================"
9465
9466 test_65m() {
9467         local layout=$(save_layout $MOUNT)
9468         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9469                 restore_layout $MOUNT $layout
9470                 error "setstripe should fail by non-root users"
9471         }
9472         true
9473 }
9474 run_test 65m "normal user can't set filesystem default stripe"
9475
9476 test_65n() {
9477         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9478         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9479                 skip "Need MDS version at least 2.12.50"
9480         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9481
9482         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9483         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9484         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9485
9486         save_layout_restore_at_exit $MOUNT
9487
9488         # new subdirectory under root directory should not inherit
9489         # the default layout from root
9490         local dir1=$MOUNT/$tdir-1
9491         mkdir $dir1 || error "mkdir $dir1 failed"
9492         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9493                 error "$dir1 shouldn't have LOV EA"
9494
9495         # delete the default layout on root directory
9496         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9497
9498         local dir2=$MOUNT/$tdir-2
9499         mkdir $dir2 || error "mkdir $dir2 failed"
9500         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9501                 error "$dir2 shouldn't have LOV EA"
9502
9503         # set a new striping pattern on root directory
9504         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9505         local new_def_stripe_size=$((def_stripe_size * 2))
9506         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9507                 error "set stripe size on $MOUNT failed"
9508
9509         # new file created in $dir2 should inherit the new stripe size from
9510         # the filesystem default
9511         local file2=$dir2/$tfile-2
9512         touch $file2 || error "touch $file2 failed"
9513
9514         local file2_stripe_size=$($LFS getstripe -S $file2)
9515         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9516         {
9517                 echo "file2_stripe_size: '$file2_stripe_size'"
9518                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9519                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9520         }
9521
9522         local dir3=$MOUNT/$tdir-3
9523         mkdir $dir3 || error "mkdir $dir3 failed"
9524         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9525         # the root layout, which is the actual default layout that will be used
9526         # when new files are created in $dir3.
9527         local dir3_layout=$(get_layout_param $dir3)
9528         local root_dir_layout=$(get_layout_param $MOUNT)
9529         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9530         {
9531                 echo "dir3_layout: '$dir3_layout'"
9532                 echo "root_dir_layout: '$root_dir_layout'"
9533                 error "$dir3 should show the default layout from $MOUNT"
9534         }
9535
9536         # set OST pool on root directory
9537         local pool=$TESTNAME
9538         pool_add $pool || error "add $pool failed"
9539         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9540                 error "add targets to $pool failed"
9541
9542         $LFS setstripe -p $pool $MOUNT ||
9543                 error "set OST pool on $MOUNT failed"
9544
9545         # new file created in $dir3 should inherit the pool from
9546         # the filesystem default
9547         local file3=$dir3/$tfile-3
9548         touch $file3 || error "touch $file3 failed"
9549
9550         local file3_pool=$($LFS getstripe -p $file3)
9551         [[ "$file3_pool" = "$pool" ]] ||
9552                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9553
9554         local dir4=$MOUNT/$tdir-4
9555         mkdir $dir4 || error "mkdir $dir4 failed"
9556         local dir4_layout=$(get_layout_param $dir4)
9557         root_dir_layout=$(get_layout_param $MOUNT)
9558         echo "$LFS getstripe -d $dir4"
9559         $LFS getstripe -d $dir4
9560         echo "$LFS getstripe -d $MOUNT"
9561         $LFS getstripe -d $MOUNT
9562         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9563         {
9564                 echo "dir4_layout: '$dir4_layout'"
9565                 echo "root_dir_layout: '$root_dir_layout'"
9566                 error "$dir4 should show the default layout from $MOUNT"
9567         }
9568
9569         # new file created in $dir4 should inherit the pool from
9570         # the filesystem default
9571         local file4=$dir4/$tfile-4
9572         touch $file4 || error "touch $file4 failed"
9573
9574         local file4_pool=$($LFS getstripe -p $file4)
9575         [[ "$file4_pool" = "$pool" ]] ||
9576                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9577
9578         # new subdirectory under non-root directory should inherit
9579         # the default layout from its parent directory
9580         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9581                 error "set directory layout on $dir4 failed"
9582
9583         local dir5=$dir4/$tdir-5
9584         mkdir $dir5 || error "mkdir $dir5 failed"
9585
9586         dir4_layout=$(get_layout_param $dir4)
9587         local dir5_layout=$(get_layout_param $dir5)
9588         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9589         {
9590                 echo "dir4_layout: '$dir4_layout'"
9591                 echo "dir5_layout: '$dir5_layout'"
9592                 error "$dir5 should inherit the default layout from $dir4"
9593         }
9594
9595         # though subdir under ROOT doesn't inherit default layout, but
9596         # its sub dir/file should be created with default layout.
9597         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9598         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9599                 skip "Need MDS version at least 2.12.59"
9600
9601         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9602         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9603         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9604
9605         if [ $default_lmv_hash == "none" ]; then
9606                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9607         else
9608                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9609                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9610         fi
9611
9612         $LFS setdirstripe -D -c 2 $MOUNT ||
9613                 error "setdirstripe -D -c 2 failed"
9614         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9615         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9616         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9617
9618         # $dir4 layout includes pool
9619         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9620         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9621                 error "pool lost on setstripe"
9622         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9623         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9624                 error "pool lost on compound layout setstripe"
9625 }
9626 run_test 65n "don't inherit default layout from root for new subdirectories"
9627
9628 test_65o() {
9629         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9630                 skip "need MDS version at least 2.14.57"
9631
9632         # set OST pool on root directory
9633         local pool=$TESTNAME
9634
9635         pool_add $pool || error "add $pool failed"
9636         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9637                 error "add targets to $pool failed"
9638
9639         local dir1=$MOUNT/$tdir
9640
9641         mkdir $dir1 || error "mkdir $dir1 failed"
9642
9643         # set a new striping pattern on root directory
9644         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9645
9646         $LFS setstripe -p $pool $dir1 ||
9647                 error "set directory layout on $dir1 failed"
9648
9649         # $dir1 layout includes pool
9650         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9651         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9652                 error "pool lost on setstripe"
9653         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9654         $LFS getstripe $dir1
9655         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9656                 error "pool lost on compound layout setstripe"
9657
9658         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9659                 error "setdirstripe failed on sub-dir with inherited pool"
9660         $LFS getstripe $dir1/dir2
9661         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9662                 error "pool lost on compound layout setdirstripe"
9663
9664         $LFS setstripe -E -1 -c 1 $dir1
9665         $LFS getstripe -d $dir1
9666         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9667                 error "pool lost on setstripe"
9668 }
9669 run_test 65o "pool inheritance for mdt component"
9670
9671 # bug 2543 - update blocks count on client
9672 test_66() {
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674
9675         local COUNT=${COUNT:-8}
9676         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9677         sync; sync_all_data; sync; sync_all_data
9678         cancel_lru_locks osc
9679         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9680         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9681 }
9682 run_test 66 "update inode blocks count on client ==============="
9683
9684 meminfo() {
9685         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9686 }
9687
9688 swap_used() {
9689         swapon -s | awk '($1 == "'$1'") { print $4 }'
9690 }
9691
9692 # bug5265, obdfilter oa2dentry return -ENOENT
9693 # #define OBD_FAIL_SRV_ENOENT 0x217
9694 test_69() {
9695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9696         remote_ost_nodsh && skip "remote OST with nodsh"
9697
9698         f="$DIR/$tfile"
9699         $LFS setstripe -c 1 -i 0 $f
9700
9701         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9702
9703         do_facet ost1 lctl set_param fail_loc=0x217
9704         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9705         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9706
9707         do_facet ost1 lctl set_param fail_loc=0
9708         $DIRECTIO write $f 0 2 || error "write error"
9709
9710         cancel_lru_locks osc
9711         $DIRECTIO read $f 0 1 || error "read error"
9712
9713         do_facet ost1 lctl set_param fail_loc=0x217
9714         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9715
9716         do_facet ost1 lctl set_param fail_loc=0
9717         rm -f $f
9718 }
9719 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9720
9721 test_71() {
9722         test_mkdir $DIR/$tdir
9723         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9724         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9725 }
9726 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9727
9728 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730         [ "$RUNAS_ID" = "$UID" ] &&
9731                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9732         # Check that testing environment is properly set up. Skip if not
9733         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9734                 skip_env "User $RUNAS_ID does not exist - skipping"
9735
9736         touch $DIR/$tfile
9737         chmod 777 $DIR/$tfile
9738         chmod ug+s $DIR/$tfile
9739         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9740                 error "$RUNAS dd $DIR/$tfile failed"
9741         # See if we are still setuid/sgid
9742         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9743                 error "S/gid is not dropped on write"
9744         # Now test that MDS is updated too
9745         cancel_lru_locks mdc
9746         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9747                 error "S/gid is not dropped on MDS"
9748         rm -f $DIR/$tfile
9749 }
9750 run_test 72a "Test that remove suid works properly (bug5695) ===="
9751
9752 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9753         local perm
9754
9755         [ "$RUNAS_ID" = "$UID" ] &&
9756                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9757         [ "$RUNAS_ID" -eq 0 ] &&
9758                 skip_env "RUNAS_ID = 0 -- skipping"
9759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9760         # Check that testing environment is properly set up. Skip if not
9761         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9762                 skip_env "User $RUNAS_ID does not exist - skipping"
9763
9764         touch $DIR/${tfile}-f{g,u}
9765         test_mkdir $DIR/${tfile}-dg
9766         test_mkdir $DIR/${tfile}-du
9767         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9768         chmod g+s $DIR/${tfile}-{f,d}g
9769         chmod u+s $DIR/${tfile}-{f,d}u
9770         for perm in 777 2777 4777; do
9771                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9772                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9773                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9774                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9775         done
9776         true
9777 }
9778 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9779
9780 # bug 3462 - multiple simultaneous MDC requests
9781 test_73() {
9782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9783
9784         test_mkdir $DIR/d73-1
9785         test_mkdir $DIR/d73-2
9786         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9787         pid1=$!
9788
9789         lctl set_param fail_loc=0x80000129
9790         $MULTIOP $DIR/d73-1/f73-2 Oc &
9791         sleep 1
9792         lctl set_param fail_loc=0
9793
9794         $MULTIOP $DIR/d73-2/f73-3 Oc &
9795         pid3=$!
9796
9797         kill -USR1 $pid1
9798         wait $pid1 || return 1
9799
9800         sleep 25
9801
9802         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9803         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9804         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9805
9806         rm -rf $DIR/d73-*
9807 }
9808 run_test 73 "multiple MDC requests (should not deadlock)"
9809
9810 test_74a() { # bug 6149, 6184
9811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9812
9813         touch $DIR/f74a
9814         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9815         #
9816         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9817         # will spin in a tight reconnection loop
9818         $LCTL set_param fail_loc=0x8000030e
9819         # get any lock that won't be difficult - lookup works.
9820         ls $DIR/f74a
9821         $LCTL set_param fail_loc=0
9822         rm -f $DIR/f74a
9823         true
9824 }
9825 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9826
9827 test_74b() { # bug 13310
9828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9829
9830         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9831         #
9832         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9833         # will spin in a tight reconnection loop
9834         $LCTL set_param fail_loc=0x8000030e
9835         # get a "difficult" lock
9836         touch $DIR/f74b
9837         $LCTL set_param fail_loc=0
9838         rm -f $DIR/f74b
9839         true
9840 }
9841 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9842
9843 test_74c() {
9844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9845
9846         #define OBD_FAIL_LDLM_NEW_LOCK
9847         $LCTL set_param fail_loc=0x319
9848         touch $DIR/$tfile && error "touch successful"
9849         $LCTL set_param fail_loc=0
9850         true
9851 }
9852 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9853
9854 slab_lic=/sys/kernel/slab/lustre_inode_cache
9855 num_objects() {
9856         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9857         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9858                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9859 }
9860
9861 test_76a() { # Now for b=20433, added originally in b=1443
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         cancel_lru_locks osc
9865         # there may be some slab objects cached per core
9866         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9867         local before=$(num_objects)
9868         local count=$((512 * cpus))
9869         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9870         local margin=$((count / 10))
9871         if [[ -f $slab_lic/aliases ]]; then
9872                 local aliases=$(cat $slab_lic/aliases)
9873                 (( aliases > 0 )) && margin=$((margin * aliases))
9874         fi
9875
9876         echo "before slab objects: $before"
9877         for i in $(seq $count); do
9878                 touch $DIR/$tfile
9879                 rm -f $DIR/$tfile
9880         done
9881         cancel_lru_locks osc
9882         local after=$(num_objects)
9883         echo "created: $count, after slab objects: $after"
9884         # shared slab counts are not very accurate, allow significant margin
9885         # the main goal is that the cache growth is not permanently > $count
9886         while (( after > before + margin )); do
9887                 sleep 1
9888                 after=$(num_objects)
9889                 wait=$((wait + 1))
9890                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9891                 if (( wait > 60 )); then
9892                         error "inode slab grew from $before+$margin to $after"
9893                 fi
9894         done
9895 }
9896 run_test 76a "confirm clients recycle inodes properly ===="
9897
9898 test_76b() {
9899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9900         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9901
9902         local count=512
9903         local before=$(num_objects)
9904
9905         for i in $(seq $count); do
9906                 mkdir $DIR/$tdir
9907                 rmdir $DIR/$tdir
9908         done
9909
9910         local after=$(num_objects)
9911         local wait=0
9912
9913         while (( after > before )); do
9914                 sleep 1
9915                 after=$(num_objects)
9916                 wait=$((wait + 1))
9917                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9918                 if (( wait > 60 )); then
9919                         error "inode slab grew from $before to $after"
9920                 fi
9921         done
9922
9923         echo "slab objects before: $before, after: $after"
9924 }
9925 run_test 76b "confirm clients recycle directory inodes properly ===="
9926
9927 export ORIG_CSUM=""
9928 set_checksums()
9929 {
9930         # Note: in sptlrpc modes which enable its own bulk checksum, the
9931         # original crc32_le bulk checksum will be automatically disabled,
9932         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9933         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9934         # In this case set_checksums() will not be no-op, because sptlrpc
9935         # bulk checksum will be enabled all through the test.
9936
9937         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9938         lctl set_param -n osc.*.checksums $1
9939         return 0
9940 }
9941
9942 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9943                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9944 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9945                              tr -d [] | head -n1)}
9946 set_checksum_type()
9947 {
9948         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9949         rc=$?
9950         log "set checksum type to $1, rc = $rc"
9951         return $rc
9952 }
9953
9954 get_osc_checksum_type()
9955 {
9956         # arugment 1: OST name, like OST0000
9957         ost=$1
9958         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9959                         sed 's/.*\[\(.*\)\].*/\1/g')
9960         rc=$?
9961         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9962         echo $checksum_type
9963 }
9964
9965 F77_TMP=$TMP/f77-temp
9966 F77SZ=8
9967 setup_f77() {
9968         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9969                 error "error writing to $F77_TMP"
9970 }
9971
9972 test_77a() { # bug 10889
9973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9974         $GSS && skip_env "could not run with gss"
9975
9976         [ ! -f $F77_TMP ] && setup_f77
9977         set_checksums 1
9978         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9979         set_checksums 0
9980         rm -f $DIR/$tfile
9981 }
9982 run_test 77a "normal checksum read/write operation"
9983
9984 test_77b() { # bug 10889
9985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9986         $GSS && skip_env "could not run with gss"
9987
9988         [ ! -f $F77_TMP ] && setup_f77
9989         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9990         $LCTL set_param fail_loc=0x80000409
9991         set_checksums 1
9992
9993         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9994                 error "dd error: $?"
9995         $LCTL set_param fail_loc=0
9996
9997         for algo in $CKSUM_TYPES; do
9998                 cancel_lru_locks osc
9999                 set_checksum_type $algo
10000                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10001                 $LCTL set_param fail_loc=0x80000408
10002                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10003                 $LCTL set_param fail_loc=0
10004         done
10005         set_checksums 0
10006         set_checksum_type $ORIG_CSUM_TYPE
10007         rm -f $DIR/$tfile
10008 }
10009 run_test 77b "checksum error on client write, read"
10010
10011 cleanup_77c() {
10012         trap 0
10013         set_checksums 0
10014         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10015         $check_ost &&
10016                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10017         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10018         $check_ost && [ -n "$ost_file_prefix" ] &&
10019                 do_facet ost1 rm -f ${ost_file_prefix}\*
10020 }
10021
10022 test_77c() {
10023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10024         $GSS && skip_env "could not run with gss"
10025         remote_ost_nodsh && skip "remote OST with nodsh"
10026
10027         local bad1
10028         local osc_file_prefix
10029         local osc_file
10030         local check_ost=false
10031         local ost_file_prefix
10032         local ost_file
10033         local orig_cksum
10034         local dump_cksum
10035         local fid
10036
10037         # ensure corruption will occur on first OSS/OST
10038         $LFS setstripe -i 0 $DIR/$tfile
10039
10040         [ ! -f $F77_TMP ] && setup_f77
10041         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10042                 error "dd write error: $?"
10043         fid=$($LFS path2fid $DIR/$tfile)
10044
10045         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10046         then
10047                 check_ost=true
10048                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10049                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10050         else
10051                 echo "OSS do not support bulk pages dump upon error"
10052         fi
10053
10054         osc_file_prefix=$($LCTL get_param -n debug_path)
10055         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10056
10057         trap cleanup_77c EXIT
10058
10059         set_checksums 1
10060         # enable bulk pages dump upon error on Client
10061         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10062         # enable bulk pages dump upon error on OSS
10063         $check_ost &&
10064                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10065
10066         # flush Client cache to allow next read to reach OSS
10067         cancel_lru_locks osc
10068
10069         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10070         $LCTL set_param fail_loc=0x80000408
10071         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10072         $LCTL set_param fail_loc=0
10073
10074         rm -f $DIR/$tfile
10075
10076         # check cksum dump on Client
10077         osc_file=$(ls ${osc_file_prefix}*)
10078         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10079         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10080         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10081         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10082         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10083                      cksum)
10084         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10085         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10086                 error "dump content does not match on Client"
10087
10088         $check_ost || skip "No need to check cksum dump on OSS"
10089
10090         # check cksum dump on OSS
10091         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10092         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10093         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10094         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10095         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10096                 error "dump content does not match on OSS"
10097
10098         cleanup_77c
10099 }
10100 run_test 77c "checksum error on client read with debug"
10101
10102 test_77d() { # bug 10889
10103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10104         $GSS && skip_env "could not run with gss"
10105
10106         stack_trap "rm -f $DIR/$tfile"
10107         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10108         $LCTL set_param fail_loc=0x80000409
10109         set_checksums 1
10110         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10111                 error "direct write: rc=$?"
10112         $LCTL set_param fail_loc=0
10113         set_checksums 0
10114
10115         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10116         $LCTL set_param fail_loc=0x80000408
10117         set_checksums 1
10118         cancel_lru_locks osc
10119         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10120                 error "direct read: rc=$?"
10121         $LCTL set_param fail_loc=0
10122         set_checksums 0
10123 }
10124 run_test 77d "checksum error on OST direct write, read"
10125
10126 test_77f() { # bug 10889
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128         $GSS && skip_env "could not run with gss"
10129
10130         set_checksums 1
10131         stack_trap "rm -f $DIR/$tfile"
10132         for algo in $CKSUM_TYPES; do
10133                 cancel_lru_locks osc
10134                 set_checksum_type $algo
10135                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10136                 $LCTL set_param fail_loc=0x409
10137                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10138                         error "direct write succeeded"
10139                 $LCTL set_param fail_loc=0
10140         done
10141         set_checksum_type $ORIG_CSUM_TYPE
10142         set_checksums 0
10143 }
10144 run_test 77f "repeat checksum error on write (expect error)"
10145
10146 test_77g() { # bug 10889
10147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10148         $GSS && skip_env "could not run with gss"
10149         remote_ost_nodsh && skip "remote OST with nodsh"
10150
10151         [ ! -f $F77_TMP ] && setup_f77
10152
10153         local file=$DIR/$tfile
10154         stack_trap "rm -f $file" EXIT
10155
10156         $LFS setstripe -c 1 -i 0 $file
10157         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10158         do_facet ost1 lctl set_param fail_loc=0x8000021a
10159         set_checksums 1
10160         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10161                 error "write error: rc=$?"
10162         do_facet ost1 lctl set_param fail_loc=0
10163         set_checksums 0
10164
10165         cancel_lru_locks osc
10166         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10167         do_facet ost1 lctl set_param fail_loc=0x8000021b
10168         set_checksums 1
10169         cmp $F77_TMP $file || error "file compare failed"
10170         do_facet ost1 lctl set_param fail_loc=0
10171         set_checksums 0
10172 }
10173 run_test 77g "checksum error on OST write, read"
10174
10175 test_77k() { # LU-10906
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177         $GSS && skip_env "could not run with gss"
10178
10179         local cksum_param="osc.$FSNAME*.checksums"
10180         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10181         local checksum
10182         local i
10183
10184         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10185         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10186         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10187
10188         for i in 0 1; do
10189                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10190                         error "failed to set checksum=$i on MGS"
10191                 wait_update $HOSTNAME "$get_checksum" $i
10192                 #remount
10193                 echo "remount client, checksum should be $i"
10194                 remount_client $MOUNT || error "failed to remount client"
10195                 checksum=$(eval $get_checksum)
10196                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10197         done
10198         # remove persistent param to avoid races with checksum mountopt below
10199         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10200                 error "failed to delete checksum on MGS"
10201
10202         for opt in "checksum" "nochecksum"; do
10203                 #remount with mount option
10204                 echo "remount client with option $opt, checksum should be $i"
10205                 umount_client $MOUNT || error "failed to umount client"
10206                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10207                         error "failed to mount client with option '$opt'"
10208                 checksum=$(eval $get_checksum)
10209                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10210                 i=$((i - 1))
10211         done
10212
10213         remount_client $MOUNT || error "failed to remount client"
10214 }
10215 run_test 77k "enable/disable checksum correctly"
10216
10217 test_77l() {
10218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10219         $GSS && skip_env "could not run with gss"
10220
10221         set_checksums 1
10222         stack_trap "set_checksums $ORIG_CSUM" EXIT
10223         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10224
10225         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10226
10227         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10228         for algo in $CKSUM_TYPES; do
10229                 set_checksum_type $algo || error "fail to set checksum type $algo"
10230                 osc_algo=$(get_osc_checksum_type OST0000)
10231                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10232
10233                 # no locks, no reqs to let the connection idle
10234                 cancel_lru_locks osc
10235                 lru_resize_disable osc
10236                 wait_osc_import_state client ost1 IDLE
10237
10238                 # ensure ost1 is connected
10239                 stat $DIR/$tfile >/dev/null || error "can't stat"
10240                 wait_osc_import_state client ost1 FULL
10241
10242                 osc_algo=$(get_osc_checksum_type OST0000)
10243                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10244         done
10245         return 0
10246 }
10247 run_test 77l "preferred checksum type is remembered after reconnected"
10248
10249 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10250 rm -f $F77_TMP
10251 unset F77_TMP
10252
10253 test_77m() {
10254         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10255                 skip "Need at least version 2.14.52"
10256         local param=checksum_speed
10257
10258         $LCTL get_param $param || error "reading $param failed"
10259
10260         csum_speeds=$($LCTL get_param -n $param)
10261
10262         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10263                 error "known checksum types are missing"
10264 }
10265 run_test 77m "Verify checksum_speed is correctly read"
10266
10267 check_filefrag_77n() {
10268         local nr_ext=0
10269         local starts=()
10270         local ends=()
10271
10272         while read extidx a b start end rest; do
10273                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10274                         nr_ext=$(( $nr_ext + 1 ))
10275                         starts+=( ${start%..} )
10276                         ends+=( ${end%:} )
10277                 fi
10278         done < <( filefrag -sv $1 )
10279
10280         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10281         return 1
10282 }
10283
10284 test_77n() {
10285         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10286
10287         touch $DIR/$tfile
10288         $TRUNCATE $DIR/$tfile 0
10289         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10290         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10291         check_filefrag_77n $DIR/$tfile ||
10292                 skip "$tfile blocks not contiguous around hole"
10293
10294         set_checksums 1
10295         stack_trap "set_checksums $ORIG_CSUM" EXIT
10296         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10297         stack_trap "rm -f $DIR/$tfile"
10298
10299         for algo in $CKSUM_TYPES; do
10300                 if [[ "$algo" =~ ^t10 ]]; then
10301                         set_checksum_type $algo ||
10302                                 error "fail to set checksum type $algo"
10303                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10304                                 error "fail to read $tfile with $algo"
10305                 fi
10306         done
10307         rm -f $DIR/$tfile
10308         return 0
10309 }
10310 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10311
10312 test_77o() {
10313         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10314                 skip "Need MDS version at least 2.14.55"
10315         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10316                 skip "Need OST version at least 2.14.55"
10317         local ofd=obdfilter
10318         local mdt=mdt
10319
10320         # print OST checksum_type
10321         echo "$ofd.$FSNAME-*.checksum_type:"
10322         do_nodes $(comma_list $(osts_nodes)) \
10323                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10324
10325         # print MDT checksum_type
10326         echo "$mdt.$FSNAME-*.checksum_type:"
10327         do_nodes $(comma_list $(mdts_nodes)) \
10328                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10329
10330         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10331                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10332
10333         (( $o_count == $OSTCOUNT )) ||
10334                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10335
10336         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10337                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10338
10339         (( $m_count == $MDSCOUNT )) ||
10340                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10341 }
10342 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10343
10344 cleanup_test_78() {
10345         trap 0
10346         rm -f $DIR/$tfile
10347 }
10348
10349 test_78() { # bug 10901
10350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10351         remote_ost || skip_env "local OST"
10352
10353         NSEQ=5
10354         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10355         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10356         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10357         echo "MemTotal: $MEMTOTAL"
10358
10359         # reserve 256MB of memory for the kernel and other running processes,
10360         # and then take 1/2 of the remaining memory for the read/write buffers.
10361         if [ $MEMTOTAL -gt 512 ] ;then
10362                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10363         else
10364                 # for those poor memory-starved high-end clusters...
10365                 MEMTOTAL=$((MEMTOTAL / 2))
10366         fi
10367         echo "Mem to use for directio: $MEMTOTAL"
10368
10369         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10370         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10371         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10372         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10373                 head -n1)
10374         echo "Smallest OST: $SMALLESTOST"
10375         [[ $SMALLESTOST -lt 10240 ]] &&
10376                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10377
10378         trap cleanup_test_78 EXIT
10379
10380         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10381                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10382
10383         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10384         echo "File size: $F78SIZE"
10385         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10386         for i in $(seq 1 $NSEQ); do
10387                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10388                 echo directIO rdwr round $i of $NSEQ
10389                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10390         done
10391
10392         cleanup_test_78
10393 }
10394 run_test 78 "handle large O_DIRECT writes correctly ============"
10395
10396 test_79() { # bug 12743
10397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10398
10399         wait_delete_completed
10400
10401         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10402         BKFREE=$(calc_osc_kbytes kbytesfree)
10403         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10404
10405         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10406         DFTOTAL=`echo $STRING | cut -d, -f1`
10407         DFUSED=`echo $STRING  | cut -d, -f2`
10408         DFAVAIL=`echo $STRING | cut -d, -f3`
10409         DFFREE=$(($DFTOTAL - $DFUSED))
10410
10411         ALLOWANCE=$((64 * $OSTCOUNT))
10412
10413         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10414            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10415                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10416         fi
10417         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10418            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10419                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10420         fi
10421         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10422            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10423                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10424         fi
10425 }
10426 run_test 79 "df report consistency check ======================="
10427
10428 test_80() { # bug 10718
10429         remote_ost_nodsh && skip "remote OST with nodsh"
10430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10431
10432         # relax strong synchronous semantics for slow backends like ZFS
10433         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10434                 local soc="obdfilter.*.sync_lock_cancel"
10435                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10436
10437                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10438                 if [ -z "$save" ]; then
10439                         soc="obdfilter.*.sync_on_lock_cancel"
10440                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10441                 fi
10442
10443                 if [ "$save" != "never" ]; then
10444                         local hosts=$(comma_list $(osts_nodes))
10445
10446                         do_nodes $hosts $LCTL set_param $soc=never
10447                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10448                 fi
10449         fi
10450
10451         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10452         sync; sleep 1; sync
10453         local before=$(date +%s)
10454         cancel_lru_locks osc
10455         local after=$(date +%s)
10456         local diff=$((after - before))
10457         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10458
10459         rm -f $DIR/$tfile
10460 }
10461 run_test 80 "Page eviction is equally fast at high offsets too"
10462
10463 test_81a() { # LU-456
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465         remote_ost_nodsh && skip "remote OST with nodsh"
10466
10467         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10468         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10469         do_facet ost1 lctl set_param fail_loc=0x80000228
10470
10471         # write should trigger a retry and success
10472         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10473         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10474         RC=$?
10475         if [ $RC -ne 0 ] ; then
10476                 error "write should success, but failed for $RC"
10477         fi
10478 }
10479 run_test 81a "OST should retry write when get -ENOSPC ==============="
10480
10481 test_81b() { # LU-456
10482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10483         remote_ost_nodsh && skip "remote OST with nodsh"
10484
10485         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10486         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10487         do_facet ost1 lctl set_param fail_loc=0x228
10488
10489         # write should retry several times and return -ENOSPC finally
10490         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10491         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10492         RC=$?
10493         ENOSPC=28
10494         if [ $RC -ne $ENOSPC ] ; then
10495                 error "dd should fail for -ENOSPC, but succeed."
10496         fi
10497 }
10498 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10499
10500 test_99() {
10501         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10502
10503         test_mkdir $DIR/$tdir.cvsroot
10504         chown $RUNAS_ID $DIR/$tdir.cvsroot
10505
10506         cd $TMP
10507         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10508
10509         cd /etc/init.d
10510         # some versions of cvs import exit(1) when asked to import links or
10511         # files they can't read.  ignore those files.
10512         local toignore=$(find . -type l -printf '-I %f\n' -o \
10513                          ! -perm /4 -printf '-I %f\n')
10514         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10515                 $tdir.reposname vtag rtag
10516
10517         cd $DIR
10518         test_mkdir $DIR/$tdir.reposname
10519         chown $RUNAS_ID $DIR/$tdir.reposname
10520         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10521
10522         cd $DIR/$tdir.reposname
10523         $RUNAS touch foo99
10524         $RUNAS cvs add -m 'addmsg' foo99
10525         $RUNAS cvs update
10526         $RUNAS cvs commit -m 'nomsg' foo99
10527         rm -fr $DIR/$tdir.cvsroot
10528 }
10529 run_test 99 "cvs strange file/directory operations"
10530
10531 test_100() {
10532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10533         [[ "$NETTYPE" =~ tcp ]] ||
10534                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10535         remote_ost_nodsh && skip "remote OST with nodsh"
10536         remote_mds_nodsh && skip "remote MDS with nodsh"
10537         remote_servers ||
10538                 skip "useless for local single node setup"
10539
10540         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10541                 [ "$PROT" != "tcp" ] && continue
10542                 RPORT=$(echo $REMOTE | cut -d: -f2)
10543                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10544
10545                 rc=0
10546                 LPORT=`echo $LOCAL | cut -d: -f2`
10547                 if [ $LPORT -ge 1024 ]; then
10548                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10549                         netstat -tna
10550                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10551                 fi
10552         done
10553         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10554 }
10555 run_test 100 "check local port using privileged port ==========="
10556
10557 function get_named_value()
10558 {
10559     local tag=$1
10560
10561     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10562 }
10563
10564 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10565                    awk '/^max_cached_mb/ { print $2 }')
10566
10567 cleanup_101a() {
10568         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10569         trap 0
10570 }
10571
10572 test_101a() {
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10574
10575         local s
10576         local discard
10577         local nreads=10000
10578         local cache_limit=32
10579
10580         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10581         trap cleanup_101a EXIT
10582         $LCTL set_param -n llite.*.read_ahead_stats=0
10583         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10584
10585         #
10586         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10587         #
10588         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10589         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10590
10591         discard=0
10592         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10593                    get_named_value 'read.but.discarded'); do
10594                         discard=$(($discard + $s))
10595         done
10596         cleanup_101a
10597
10598         $LCTL get_param osc.*-osc*.rpc_stats
10599         $LCTL get_param llite.*.read_ahead_stats
10600
10601         # Discard is generally zero, but sometimes a few random reads line up
10602         # and trigger larger readahead, which is wasted & leads to discards.
10603         if [[ $(($discard)) -gt $nreads ]]; then
10604                 error "too many ($discard) discarded pages"
10605         fi
10606         rm -f $DIR/$tfile || true
10607 }
10608 run_test 101a "check read-ahead for random reads"
10609
10610 setup_test101bc() {
10611         test_mkdir $DIR/$tdir
10612         local ssize=$1
10613         local FILE_LENGTH=$2
10614         STRIPE_OFFSET=0
10615
10616         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10617
10618         local list=$(comma_list $(osts_nodes))
10619         set_osd_param $list '' read_cache_enable 0
10620         set_osd_param $list '' writethrough_cache_enable 0
10621
10622         trap cleanup_test101bc EXIT
10623         # prepare the read-ahead file
10624         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10625
10626         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10627                                 count=$FILE_SIZE_MB 2> /dev/null
10628
10629 }
10630
10631 cleanup_test101bc() {
10632         trap 0
10633         rm -rf $DIR/$tdir
10634         rm -f $DIR/$tfile
10635
10636         local list=$(comma_list $(osts_nodes))
10637         set_osd_param $list '' read_cache_enable 1
10638         set_osd_param $list '' writethrough_cache_enable 1
10639 }
10640
10641 calc_total() {
10642         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10643 }
10644
10645 ra_check_101() {
10646         local read_size=$1
10647         local stripe_size=$2
10648         local stride_length=$((stripe_size / read_size))
10649         local stride_width=$((stride_length * OSTCOUNT))
10650         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10651                                 (stride_width - stride_length) ))
10652         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10653                   get_named_value 'read.but.discarded' | calc_total)
10654
10655         if [[ $discard -gt $discard_limit ]]; then
10656                 $LCTL get_param llite.*.read_ahead_stats
10657                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10658         else
10659                 echo "Read-ahead success for size ${read_size}"
10660         fi
10661 }
10662
10663 test_101b() {
10664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10665         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10666
10667         local STRIPE_SIZE=1048576
10668         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10669
10670         if [ $SLOW == "yes" ]; then
10671                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10672         else
10673                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10674         fi
10675
10676         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10677
10678         # prepare the read-ahead file
10679         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10680         cancel_lru_locks osc
10681         for BIDX in 2 4 8 16 32 64 128 256
10682         do
10683                 local BSIZE=$((BIDX*4096))
10684                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10685                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10686                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10687                 $LCTL set_param -n llite.*.read_ahead_stats=0
10688                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10689                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10690                 cancel_lru_locks osc
10691                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10692         done
10693         cleanup_test101bc
10694         true
10695 }
10696 run_test 101b "check stride-io mode read-ahead ================="
10697
10698 test_101c() {
10699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10700
10701         local STRIPE_SIZE=1048576
10702         local FILE_LENGTH=$((STRIPE_SIZE*100))
10703         local nreads=10000
10704         local rsize=65536
10705         local osc_rpc_stats
10706
10707         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10708
10709         cancel_lru_locks osc
10710         $LCTL set_param osc.*.rpc_stats=0
10711         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10712         $LCTL get_param osc.*.rpc_stats
10713         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10714                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10715                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10716                 local size
10717
10718                 if [ $lines -le 20 ]; then
10719                         echo "continue debug"
10720                         continue
10721                 fi
10722                 for size in 1 2 4 8; do
10723                         local rpc=$(echo "$stats" |
10724                                     awk '($1 == "'$size':") {print $2; exit; }')
10725                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10726                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10727                 done
10728                 echo "$osc_rpc_stats check passed!"
10729         done
10730         cleanup_test101bc
10731         true
10732 }
10733 run_test 101c "check stripe_size aligned read-ahead"
10734
10735 test_101d() {
10736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10737
10738         local file=$DIR/$tfile
10739         local sz_MB=${FILESIZE_101d:-80}
10740         local ra_MB=${READAHEAD_MB:-40}
10741
10742         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10743         [ $free_MB -lt $sz_MB ] &&
10744                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10745
10746         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10747         $LFS setstripe -c -1 $file || error "setstripe failed"
10748
10749         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10750         echo Cancel LRU locks on lustre client to flush the client cache
10751         cancel_lru_locks osc
10752
10753         echo Disable read-ahead
10754         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10755         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10756         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10757         $LCTL get_param -n llite.*.max_read_ahead_mb
10758
10759         echo "Reading the test file $file with read-ahead disabled"
10760         local sz_KB=$((sz_MB * 1024 / 4))
10761         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10762         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10763         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10764                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10765
10766         echo "Cancel LRU locks on lustre client to flush the client cache"
10767         cancel_lru_locks osc
10768         echo Enable read-ahead with ${ra_MB}MB
10769         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10770
10771         echo "Reading the test file $file with read-ahead enabled"
10772         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10773                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10774
10775         echo "read-ahead disabled time read $raOFF"
10776         echo "read-ahead enabled time read $raON"
10777
10778         rm -f $file
10779         wait_delete_completed
10780
10781         # use awk for this check instead of bash because it handles decimals
10782         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10783                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10784 }
10785 run_test 101d "file read with and without read-ahead enabled"
10786
10787 test_101e() {
10788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10789
10790         local file=$DIR/$tfile
10791         local size_KB=500  #KB
10792         local count=100
10793         local bsize=1024
10794
10795         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10796         local need_KB=$((count * size_KB))
10797         [[ $free_KB -le $need_KB ]] &&
10798                 skip_env "Need free space $need_KB, have $free_KB"
10799
10800         echo "Creating $count ${size_KB}K test files"
10801         for ((i = 0; i < $count; i++)); do
10802                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10803         done
10804
10805         echo "Cancel LRU locks on lustre client to flush the client cache"
10806         cancel_lru_locks $OSC
10807
10808         echo "Reset readahead stats"
10809         $LCTL set_param -n llite.*.read_ahead_stats=0
10810
10811         for ((i = 0; i < $count; i++)); do
10812                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10813         done
10814
10815         $LCTL get_param llite.*.max_cached_mb
10816         $LCTL get_param llite.*.read_ahead_stats
10817         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10818                      get_named_value 'misses' | calc_total)
10819
10820         for ((i = 0; i < $count; i++)); do
10821                 rm -rf $file.$i 2>/dev/null
10822         done
10823
10824         #10000 means 20% reads are missing in readahead
10825         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10826 }
10827 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10828
10829 test_101f() {
10830         which iozone || skip_env "no iozone installed"
10831
10832         local old_debug=$($LCTL get_param debug)
10833         old_debug=${old_debug#*=}
10834         $LCTL set_param debug="reada mmap"
10835
10836         # create a test file
10837         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10838
10839         echo Cancel LRU locks on lustre client to flush the client cache
10840         cancel_lru_locks osc
10841
10842         echo Reset readahead stats
10843         $LCTL set_param -n llite.*.read_ahead_stats=0
10844
10845         echo mmap read the file with small block size
10846         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10847                 > /dev/null 2>&1
10848
10849         echo checking missing pages
10850         $LCTL get_param llite.*.read_ahead_stats
10851         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10852                         get_named_value 'misses' | calc_total)
10853
10854         $LCTL set_param debug="$old_debug"
10855         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10856         rm -f $DIR/$tfile
10857 }
10858 run_test 101f "check mmap read performance"
10859
10860 test_101g_brw_size_test() {
10861         local mb=$1
10862         local pages=$((mb * 1048576 / PAGE_SIZE))
10863         local file=$DIR/$tfile
10864
10865         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10866                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10867         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10868                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10869                         return 2
10870         done
10871
10872         stack_trap "rm -f $file" EXIT
10873         $LCTL set_param -n osc.*.rpc_stats=0
10874
10875         # 10 RPCs should be enough for the test
10876         local count=10
10877         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10878                 { error "dd write ${mb} MB blocks failed"; return 3; }
10879         cancel_lru_locks osc
10880         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10881                 { error "dd write ${mb} MB blocks failed"; return 4; }
10882
10883         # calculate number of full-sized read and write RPCs
10884         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10885                 sed -n '/pages per rpc/,/^$/p' |
10886                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10887                 END { print reads,writes }'))
10888         # allow one extra full-sized read RPC for async readahead
10889         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10890                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10891         [[ ${rpcs[1]} == $count ]] ||
10892                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10893 }
10894
10895 test_101g() {
10896         remote_ost_nodsh && skip "remote OST with nodsh"
10897
10898         local rpcs
10899         local osts=$(get_facets OST)
10900         local list=$(comma_list $(osts_nodes))
10901         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10902         local brw_size="obdfilter.*.brw_size"
10903
10904         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10905
10906         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10907
10908         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10909                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10910                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10911            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10912                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10913                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10914
10915                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10916                         suffix="M"
10917
10918                 if [[ $orig_mb -lt 16 ]]; then
10919                         save_lustre_params $osts "$brw_size" > $p
10920                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10921                                 error "set 16MB RPC size failed"
10922
10923                         echo "remount client to enable new RPC size"
10924                         remount_client $MOUNT || error "remount_client failed"
10925                 fi
10926
10927                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10928                 # should be able to set brw_size=12, but no rpc_stats for that
10929                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10930         fi
10931
10932         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10933
10934         if [[ $orig_mb -lt 16 ]]; then
10935                 restore_lustre_params < $p
10936                 remount_client $MOUNT || error "remount_client restore failed"
10937         fi
10938
10939         rm -f $p $DIR/$tfile
10940 }
10941 run_test 101g "Big bulk(4/16 MiB) readahead"
10942
10943 test_101h() {
10944         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10945
10946         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10947                 error "dd 70M file failed"
10948         echo Cancel LRU locks on lustre client to flush the client cache
10949         cancel_lru_locks osc
10950
10951         echo "Reset readahead stats"
10952         $LCTL set_param -n llite.*.read_ahead_stats 0
10953
10954         echo "Read 10M of data but cross 64M bundary"
10955         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10956         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10957                      get_named_value 'misses' | calc_total)
10958         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10959         rm -f $p $DIR/$tfile
10960 }
10961 run_test 101h "Readahead should cover current read window"
10962
10963 test_101i() {
10964         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10965                 error "dd 10M file failed"
10966
10967         local max_per_file_mb=$($LCTL get_param -n \
10968                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10969         cancel_lru_locks osc
10970         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10971         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10972                 error "set max_read_ahead_per_file_mb to 1 failed"
10973
10974         echo "Reset readahead stats"
10975         $LCTL set_param llite.*.read_ahead_stats=0
10976
10977         dd if=$DIR/$tfile of=/dev/null bs=2M
10978
10979         $LCTL get_param llite.*.read_ahead_stats
10980         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10981                      awk '/misses/ { print $2 }')
10982         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10983         rm -f $DIR/$tfile
10984 }
10985 run_test 101i "allow current readahead to exceed reservation"
10986
10987 test_101j() {
10988         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10989                 error "setstripe $DIR/$tfile failed"
10990         local file_size=$((1048576 * 16))
10991         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10992         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10993
10994         echo Disable read-ahead
10995         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10996
10997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10998         for blk in $PAGE_SIZE 1048576 $file_size; do
10999                 cancel_lru_locks osc
11000                 echo "Reset readahead stats"
11001                 $LCTL set_param -n llite.*.read_ahead_stats=0
11002                 local count=$(($file_size / $blk))
11003                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11004                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11005                              get_named_value 'failed.to.fast.read' | calc_total)
11006                 $LCTL get_param -n llite.*.read_ahead_stats
11007                 [ $miss -eq $count ] || error "expected $count got $miss"
11008         done
11009
11010         rm -f $p $DIR/$tfile
11011 }
11012 run_test 101j "A complete read block should be submitted when no RA"
11013
11014 setup_test102() {
11015         test_mkdir $DIR/$tdir
11016         chown $RUNAS_ID $DIR/$tdir
11017         STRIPE_SIZE=65536
11018         STRIPE_OFFSET=1
11019         STRIPE_COUNT=$OSTCOUNT
11020         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11021
11022         trap cleanup_test102 EXIT
11023         cd $DIR
11024         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11025         cd $DIR/$tdir
11026         for num in 1 2 3 4; do
11027                 for count in $(seq 1 $STRIPE_COUNT); do
11028                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11029                                 local size=`expr $STRIPE_SIZE \* $num`
11030                                 local file=file"$num-$idx-$count"
11031                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11032                         done
11033                 done
11034         done
11035
11036         cd $DIR
11037         $1 tar cf $TMP/f102.tar $tdir --xattrs
11038 }
11039
11040 cleanup_test102() {
11041         trap 0
11042         rm -f $TMP/f102.tar
11043         rm -rf $DIR/d0.sanity/d102
11044 }
11045
11046 test_102a() {
11047         [ "$UID" != 0 ] && skip "must run as root"
11048         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11049                 skip_env "must have user_xattr"
11050
11051         [ -z "$(which setfattr 2>/dev/null)" ] &&
11052                 skip_env "could not find setfattr"
11053
11054         local testfile=$DIR/$tfile
11055
11056         touch $testfile
11057         echo "set/get xattr..."
11058         setfattr -n trusted.name1 -v value1 $testfile ||
11059                 error "setfattr -n trusted.name1=value1 $testfile failed"
11060         getfattr -n trusted.name1 $testfile 2> /dev/null |
11061           grep "trusted.name1=.value1" ||
11062                 error "$testfile missing trusted.name1=value1"
11063
11064         setfattr -n user.author1 -v author1 $testfile ||
11065                 error "setfattr -n user.author1=author1 $testfile failed"
11066         getfattr -n user.author1 $testfile 2> /dev/null |
11067           grep "user.author1=.author1" ||
11068                 error "$testfile missing trusted.author1=author1"
11069
11070         echo "listxattr..."
11071         setfattr -n trusted.name2 -v value2 $testfile ||
11072                 error "$testfile unable to set trusted.name2"
11073         setfattr -n trusted.name3 -v value3 $testfile ||
11074                 error "$testfile unable to set trusted.name3"
11075         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11076             grep "trusted.name" | wc -l) -eq 3 ] ||
11077                 error "$testfile missing 3 trusted.name xattrs"
11078
11079         setfattr -n user.author2 -v author2 $testfile ||
11080                 error "$testfile unable to set user.author2"
11081         setfattr -n user.author3 -v author3 $testfile ||
11082                 error "$testfile unable to set user.author3"
11083         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11084             grep "user.author" | wc -l) -eq 3 ] ||
11085                 error "$testfile missing 3 user.author xattrs"
11086
11087         echo "remove xattr..."
11088         setfattr -x trusted.name1 $testfile ||
11089                 error "$testfile error deleting trusted.name1"
11090         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11091                 error "$testfile did not delete trusted.name1 xattr"
11092
11093         setfattr -x user.author1 $testfile ||
11094                 error "$testfile error deleting user.author1"
11095         echo "set lustre special xattr ..."
11096         $LFS setstripe -c1 $testfile
11097         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11098                 awk -F "=" '/trusted.lov/ { print $2 }' )
11099         setfattr -n "trusted.lov" -v $lovea $testfile ||
11100                 error "$testfile doesn't ignore setting trusted.lov again"
11101         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11102                 error "$testfile allow setting invalid trusted.lov"
11103         rm -f $testfile
11104 }
11105 run_test 102a "user xattr test =================================="
11106
11107 check_102b_layout() {
11108         local layout="$*"
11109         local testfile=$DIR/$tfile
11110
11111         echo "test layout '$layout'"
11112         $LFS setstripe $layout $testfile || error "setstripe failed"
11113         $LFS getstripe -y $testfile
11114
11115         echo "get/set/list trusted.lov xattr ..." # b=10930
11116         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11117         [[ "$value" =~ "trusted.lov" ]] ||
11118                 error "can't get trusted.lov from $testfile"
11119         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11120                 error "getstripe failed"
11121
11122         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11123
11124         value=$(cut -d= -f2 <<<$value)
11125         # LU-13168: truncated xattr should fail if short lov_user_md header
11126         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11127                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11128         for len in $lens; do
11129                 echo "setfattr $len $testfile.2"
11130                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11131                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11132         done
11133         local stripe_size=$($LFS getstripe -S $testfile.2)
11134         local stripe_count=$($LFS getstripe -c $testfile.2)
11135         [[ $stripe_size -eq 65536 ]] ||
11136                 error "stripe size $stripe_size != 65536"
11137         [[ $stripe_count -eq $stripe_count_orig ]] ||
11138                 error "stripe count $stripe_count != $stripe_count_orig"
11139         rm $testfile $testfile.2
11140 }
11141
11142 test_102b() {
11143         [ -z "$(which setfattr 2>/dev/null)" ] &&
11144                 skip_env "could not find setfattr"
11145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11146
11147         # check plain layout
11148         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11149
11150         # and also check composite layout
11151         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11152
11153 }
11154 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11155
11156 test_102c() {
11157         [ -z "$(which setfattr 2>/dev/null)" ] &&
11158                 skip_env "could not find setfattr"
11159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11160
11161         # b10930: get/set/list lustre.lov xattr
11162         echo "get/set/list lustre.lov xattr ..."
11163         test_mkdir $DIR/$tdir
11164         chown $RUNAS_ID $DIR/$tdir
11165         local testfile=$DIR/$tdir/$tfile
11166         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11167                 error "setstripe failed"
11168         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11169                 error "getstripe failed"
11170         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11171         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11172
11173         local testfile2=${testfile}2
11174         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11175                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11176
11177         $RUNAS $MCREATE $testfile2
11178         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11179         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11180         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11181         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11182         [ $stripe_count -eq $STRIPECOUNT ] ||
11183                 error "stripe count $stripe_count != $STRIPECOUNT"
11184 }
11185 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11186
11187 compare_stripe_info1() {
11188         local stripe_index_all_zero=true
11189
11190         for num in 1 2 3 4; do
11191                 for count in $(seq 1 $STRIPE_COUNT); do
11192                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11193                                 local size=$((STRIPE_SIZE * num))
11194                                 local file=file"$num-$offset-$count"
11195                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11196                                 [[ $stripe_size -ne $size ]] &&
11197                                     error "$file: size $stripe_size != $size"
11198                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11199                                 # allow fewer stripes to be created, ORI-601
11200                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11201                                     error "$file: count $stripe_count != $count"
11202                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11203                                 [[ $stripe_index -ne 0 ]] &&
11204                                         stripe_index_all_zero=false
11205                         done
11206                 done
11207         done
11208         $stripe_index_all_zero &&
11209                 error "all files are being extracted starting from OST index 0"
11210         return 0
11211 }
11212
11213 have_xattrs_include() {
11214         tar --help | grep -q xattrs-include &&
11215                 echo --xattrs-include="lustre.*"
11216 }
11217
11218 test_102d() {
11219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11220         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11221
11222         XINC=$(have_xattrs_include)
11223         setup_test102
11224         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11225         cd $DIR/$tdir/$tdir
11226         compare_stripe_info1
11227 }
11228 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11229
11230 test_102f() {
11231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11233
11234         XINC=$(have_xattrs_include)
11235         setup_test102
11236         test_mkdir $DIR/$tdir.restore
11237         cd $DIR
11238         tar cf - --xattrs $tdir | tar xf - \
11239                 -C $DIR/$tdir.restore --xattrs $XINC
11240         cd $DIR/$tdir.restore/$tdir
11241         compare_stripe_info1
11242 }
11243 run_test 102f "tar copy files, not keep osts"
11244
11245 grow_xattr() {
11246         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11247                 skip "must have user_xattr"
11248         [ -z "$(which setfattr 2>/dev/null)" ] &&
11249                 skip_env "could not find setfattr"
11250         [ -z "$(which getfattr 2>/dev/null)" ] &&
11251                 skip_env "could not find getfattr"
11252
11253         local xsize=${1:-1024}  # in bytes
11254         local file=$DIR/$tfile
11255         local value="$(generate_string $xsize)"
11256         local xbig=trusted.big
11257         local toobig=$2
11258
11259         touch $file
11260         log "save $xbig on $file"
11261         if [ -z "$toobig" ]
11262         then
11263                 setfattr -n $xbig -v $value $file ||
11264                         error "saving $xbig on $file failed"
11265         else
11266                 setfattr -n $xbig -v $value $file &&
11267                         error "saving $xbig on $file succeeded"
11268                 return 0
11269         fi
11270
11271         local orig=$(get_xattr_value $xbig $file)
11272         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11273
11274         local xsml=trusted.sml
11275         log "save $xsml on $file"
11276         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11277
11278         local new=$(get_xattr_value $xbig $file)
11279         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11280
11281         log "grow $xsml on $file"
11282         setfattr -n $xsml -v "$value" $file ||
11283                 error "growing $xsml on $file failed"
11284
11285         new=$(get_xattr_value $xbig $file)
11286         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11287         log "$xbig still valid after growing $xsml"
11288
11289         rm -f $file
11290 }
11291
11292 test_102h() { # bug 15777
11293         grow_xattr 1024
11294 }
11295 run_test 102h "grow xattr from inside inode to external block"
11296
11297 test_102ha() {
11298         large_xattr_enabled || skip_env "ea_inode feature disabled"
11299
11300         echo "setting xattr of max xattr size: $(max_xattr_size)"
11301         grow_xattr $(max_xattr_size)
11302
11303         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11304         echo "This should fail:"
11305         grow_xattr $(($(max_xattr_size) + 10)) 1
11306 }
11307 run_test 102ha "grow xattr from inside inode to external inode"
11308
11309 test_102i() { # bug 17038
11310         [ -z "$(which getfattr 2>/dev/null)" ] &&
11311                 skip "could not find getfattr"
11312
11313         touch $DIR/$tfile
11314         ln -s $DIR/$tfile $DIR/${tfile}link
11315         getfattr -n trusted.lov $DIR/$tfile ||
11316                 error "lgetxattr on $DIR/$tfile failed"
11317         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11318                 grep -i "no such attr" ||
11319                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11320         rm -f $DIR/$tfile $DIR/${tfile}link
11321 }
11322 run_test 102i "lgetxattr test on symbolic link ============"
11323
11324 test_102j() {
11325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11326         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11327
11328         XINC=$(have_xattrs_include)
11329         setup_test102 "$RUNAS"
11330         chown $RUNAS_ID $DIR/$tdir
11331         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11332         cd $DIR/$tdir/$tdir
11333         compare_stripe_info1 "$RUNAS"
11334 }
11335 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11336
11337 test_102k() {
11338         [ -z "$(which setfattr 2>/dev/null)" ] &&
11339                 skip "could not find setfattr"
11340
11341         touch $DIR/$tfile
11342         # b22187 just check that does not crash for regular file.
11343         setfattr -n trusted.lov $DIR/$tfile
11344         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11345         local test_kdir=$DIR/$tdir
11346         test_mkdir $test_kdir
11347         local default_size=$($LFS getstripe -S $test_kdir)
11348         local default_count=$($LFS getstripe -c $test_kdir)
11349         local default_offset=$($LFS getstripe -i $test_kdir)
11350         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11351                 error 'dir setstripe failed'
11352         setfattr -n trusted.lov $test_kdir
11353         local stripe_size=$($LFS getstripe -S $test_kdir)
11354         local stripe_count=$($LFS getstripe -c $test_kdir)
11355         local stripe_offset=$($LFS getstripe -i $test_kdir)
11356         [ $stripe_size -eq $default_size ] ||
11357                 error "stripe size $stripe_size != $default_size"
11358         [ $stripe_count -eq $default_count ] ||
11359                 error "stripe count $stripe_count != $default_count"
11360         [ $stripe_offset -eq $default_offset ] ||
11361                 error "stripe offset $stripe_offset != $default_offset"
11362         rm -rf $DIR/$tfile $test_kdir
11363 }
11364 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11365
11366 test_102l() {
11367         [ -z "$(which getfattr 2>/dev/null)" ] &&
11368                 skip "could not find getfattr"
11369
11370         # LU-532 trusted. xattr is invisible to non-root
11371         local testfile=$DIR/$tfile
11372
11373         touch $testfile
11374
11375         echo "listxattr as user..."
11376         chown $RUNAS_ID $testfile
11377         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11378             grep -q "trusted" &&
11379                 error "$testfile trusted xattrs are user visible"
11380
11381         return 0;
11382 }
11383 run_test 102l "listxattr size test =================================="
11384
11385 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11386         local path=$DIR/$tfile
11387         touch $path
11388
11389         listxattr_size_check $path || error "listattr_size_check $path failed"
11390 }
11391 run_test 102m "Ensure listxattr fails on small bufffer ========"
11392
11393 cleanup_test102
11394
11395 getxattr() { # getxattr path name
11396         # Return the base64 encoding of the value of xattr name on path.
11397         local path=$1
11398         local name=$2
11399
11400         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11401         # file: $path
11402         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11403         #
11404         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11405
11406         getfattr --absolute-names --encoding=base64 --name=$name $path |
11407                 awk -F= -v name=$name '$1 == name {
11408                         print substr($0, index($0, "=") + 1);
11409         }'
11410 }
11411
11412 test_102n() { # LU-4101 mdt: protect internal xattrs
11413         [ -z "$(which setfattr 2>/dev/null)" ] &&
11414                 skip "could not find setfattr"
11415         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11416         then
11417                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11418         fi
11419
11420         local file0=$DIR/$tfile.0
11421         local file1=$DIR/$tfile.1
11422         local xattr0=$TMP/$tfile.0
11423         local xattr1=$TMP/$tfile.1
11424         local namelist="lov lma lmv link fid version som hsm"
11425         local name
11426         local value
11427
11428         rm -rf $file0 $file1 $xattr0 $xattr1
11429         touch $file0 $file1
11430
11431         # Get 'before' xattrs of $file1.
11432         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11433
11434         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11435                 namelist+=" lfsck_namespace"
11436         for name in $namelist; do
11437                 # Try to copy xattr from $file0 to $file1.
11438                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11439
11440                 setfattr --name=trusted.$name --value="$value" $file1 ||
11441                         error "setxattr 'trusted.$name' failed"
11442
11443                 # Try to set a garbage xattr.
11444                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11445
11446                 if [[ x$name == "xlov" ]]; then
11447                         setfattr --name=trusted.lov --value="$value" $file1 &&
11448                         error "setxattr invalid 'trusted.lov' success"
11449                 else
11450                         setfattr --name=trusted.$name --value="$value" $file1 ||
11451                                 error "setxattr invalid 'trusted.$name' failed"
11452                 fi
11453
11454                 # Try to remove the xattr from $file1. We don't care if this
11455                 # appears to succeed or fail, we just don't want there to be
11456                 # any changes or crashes.
11457                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11458         done
11459
11460         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11461         then
11462                 name="lfsck_ns"
11463                 # Try to copy xattr from $file0 to $file1.
11464                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11465
11466                 setfattr --name=trusted.$name --value="$value" $file1 ||
11467                         error "setxattr 'trusted.$name' failed"
11468
11469                 # Try to set a garbage xattr.
11470                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11471
11472                 setfattr --name=trusted.$name --value="$value" $file1 ||
11473                         error "setxattr 'trusted.$name' failed"
11474
11475                 # Try to remove the xattr from $file1. We don't care if this
11476                 # appears to succeed or fail, we just don't want there to be
11477                 # any changes or crashes.
11478                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11479         fi
11480
11481         # Get 'after' xattrs of file1.
11482         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11483
11484         if ! diff $xattr0 $xattr1; then
11485                 error "before and after xattrs of '$file1' differ"
11486         fi
11487
11488         rm -rf $file0 $file1 $xattr0 $xattr1
11489
11490         return 0
11491 }
11492 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11493
11494 test_102p() { # LU-4703 setxattr did not check ownership
11495         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11496                 skip "MDS needs to be at least 2.5.56"
11497
11498         local testfile=$DIR/$tfile
11499
11500         touch $testfile
11501
11502         echo "setfacl as user..."
11503         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11504         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11505
11506         echo "setfattr as user..."
11507         setfacl -m "u:$RUNAS_ID:---" $testfile
11508         $RUNAS setfattr -x system.posix_acl_access $testfile
11509         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11510 }
11511 run_test 102p "check setxattr(2) correctly fails without permission"
11512
11513 test_102q() {
11514         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11515                 skip "MDS needs to be at least 2.6.92"
11516
11517         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11518 }
11519 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11520
11521 test_102r() {
11522         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11523                 skip "MDS needs to be at least 2.6.93"
11524
11525         touch $DIR/$tfile || error "touch"
11526         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11527         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11528         rm $DIR/$tfile || error "rm"
11529
11530         #normal directory
11531         mkdir -p $DIR/$tdir || error "mkdir"
11532         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11533         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11534         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11535                 error "$testfile error deleting user.author1"
11536         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11537                 grep "user.$(basename $tdir)" &&
11538                 error "$tdir did not delete user.$(basename $tdir)"
11539         rmdir $DIR/$tdir || error "rmdir"
11540
11541         #striped directory
11542         test_mkdir $DIR/$tdir
11543         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11544         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11545         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11546                 error "$testfile error deleting user.author1"
11547         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11548                 grep "user.$(basename $tdir)" &&
11549                 error "$tdir did not delete user.$(basename $tdir)"
11550         rmdir $DIR/$tdir || error "rm striped dir"
11551 }
11552 run_test 102r "set EAs with empty values"
11553
11554 test_102s() {
11555         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11556                 skip "MDS needs to be at least 2.11.52"
11557
11558         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11559
11560         save_lustre_params client "llite.*.xattr_cache" > $save
11561
11562         for cache in 0 1; do
11563                 lctl set_param llite.*.xattr_cache=$cache
11564
11565                 rm -f $DIR/$tfile
11566                 touch $DIR/$tfile || error "touch"
11567                 for prefix in lustre security system trusted user; do
11568                         # Note getxattr() may fail with 'Operation not
11569                         # supported' or 'No such attribute' depending
11570                         # on prefix and cache.
11571                         getfattr -n $prefix.n102s $DIR/$tfile &&
11572                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11573                 done
11574         done
11575
11576         restore_lustre_params < $save
11577 }
11578 run_test 102s "getting nonexistent xattrs should fail"
11579
11580 test_102t() {
11581         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11582                 skip "MDS needs to be at least 2.11.52"
11583
11584         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11585
11586         save_lustre_params client "llite.*.xattr_cache" > $save
11587
11588         for cache in 0 1; do
11589                 lctl set_param llite.*.xattr_cache=$cache
11590
11591                 for buf_size in 0 256; do
11592                         rm -f $DIR/$tfile
11593                         touch $DIR/$tfile || error "touch"
11594                         setfattr -n user.multiop $DIR/$tfile
11595                         $MULTIOP $DIR/$tfile oa$buf_size ||
11596                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11597                 done
11598         done
11599
11600         restore_lustre_params < $save
11601 }
11602 run_test 102t "zero length xattr values handled correctly"
11603
11604 run_acl_subtest()
11605 {
11606         local test=$LUSTRE/tests/acl/$1.test
11607         local tmp=$(mktemp -t $1-XXXXXX).test
11608         local bin=$2
11609         local dmn=$3
11610         local grp=$4
11611         local nbd=$5
11612         export LANG=C
11613
11614
11615         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11616         local sedgroups="-e s/:users/:$grp/g"
11617         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11618
11619         sed $sedusers $sedgroups < $test > $tmp
11620         stack_trap "rm -f $tmp"
11621         [[ -s $tmp ]] || error "sed failed to create test script"
11622
11623         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11624         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11625 }
11626
11627 test_103a() {
11628         [ "$UID" != 0 ] && skip "must run as root"
11629         $GSS && skip_env "could not run under gss"
11630         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11631                 skip_env "must have acl enabled"
11632         which setfacl || skip_env "could not find setfacl"
11633         remote_mds_nodsh && skip "remote MDS with nodsh"
11634
11635         ACLBIN=${ACLBIN:-"bin"}
11636         ACLDMN=${ACLDMN:-"daemon"}
11637         ACLGRP=${ACLGRP:-"users"}
11638         ACLNBD=${ACLNBD:-"nobody"}
11639
11640         if ! id $ACLBIN ||
11641            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11642                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11643                 ACLBIN=$USER0
11644                 if ! id $ACLBIN ; then
11645                         cat /etc/passwd
11646                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11647                 fi
11648         fi
11649         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11650            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11651                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11652                 ACLDMN=$USER1
11653                 if ! id $ACLDMN ; then
11654                         cat /etc/passwd
11655                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11656                 fi
11657         fi
11658         if ! getent group $ACLGRP; then
11659                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11660                 ACLGRP="$TSTUSR"
11661                 if ! getent group $ACLGRP; then
11662                         echo "cannot find group '$ACLGRP', adding it"
11663                         cat /etc/group
11664                         add_group 60000 $ACLGRP
11665                 fi
11666         fi
11667
11668         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11669         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11670         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11671
11672         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11673                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11674                 ACLGRP="$TSTUSR"
11675                 if ! getent group $ACLGRP; then
11676                         echo "cannot find group '$ACLGRP', adding it"
11677                         cat /etc/group
11678                         add_group 60000 $ACLGRP
11679                 fi
11680                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11681                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11682                         cat /etc/group
11683                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11684                 fi
11685         fi
11686
11687         gpasswd -a $ACLDMN $ACLBIN ||
11688                 error "setting client group failed"             # LU-5641
11689         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11690                 error "setting MDS group failed"                # LU-5641
11691
11692         declare -a identity_old
11693
11694         for num in $(seq $MDSCOUNT); do
11695                 switch_identity $num true || identity_old[$num]=$?
11696         done
11697
11698         SAVE_UMASK=$(umask)
11699         umask 0022
11700         mkdir -p $DIR/$tdir
11701         cd $DIR/$tdir
11702
11703         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11704         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11705         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11706         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11707         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11708         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11709         if ! id -u $ACLNBD ||
11710            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11711                 ACLNBD="nfsnobody"
11712                 if ! id -u $ACLNBD; then
11713                         ACLNBD=""
11714                 fi
11715         fi
11716         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11717                 add_group $(id -u $ACLNBD) $ACLNBD
11718                 if ! getent group $ACLNBD; then
11719                         ACLNBD=""
11720                 fi
11721         fi
11722         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11723            [[ -n "$ACLNBD" ]] && which setfattr; then
11724                 run_acl_subtest permissions_xattr \
11725                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11726         elif [[ -z "$ACLNBD" ]]; then
11727                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11728         else
11729                 echo "skip 'permission_xattr' test - missing setfattr command"
11730         fi
11731         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11732
11733         # inheritance test got from HP
11734         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11735         chmod +x make-tree || error "chmod +x failed"
11736         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11737         rm -f make-tree
11738
11739         echo "LU-974 ignore umask when acl is enabled..."
11740         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11741         if [ $MDSCOUNT -ge 2 ]; then
11742                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11743         fi
11744
11745         echo "LU-2561 newly created file is same size as directory..."
11746         if [ "$mds1_FSTYPE" != "zfs" ]; then
11747                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11748         else
11749                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11750         fi
11751
11752         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11753
11754         cd $SAVE_PWD
11755         umask $SAVE_UMASK
11756
11757         for num in $(seq $MDSCOUNT); do
11758                 if [ "${identity_old[$num]}" = 1 ]; then
11759                         switch_identity $num false || identity_old[$num]=$?
11760                 fi
11761         done
11762 }
11763 run_test 103a "acl test"
11764
11765 test_103b() {
11766         declare -a pids
11767         local U
11768
11769         for U in {0..511}; do
11770                 {
11771                 local O=$(printf "%04o" $U)
11772
11773                 umask $(printf "%04o" $((511 ^ $O)))
11774                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11775                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11776
11777                 (( $S == ($O & 0666) )) ||
11778                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11779
11780                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11781                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11782                 (( $S == ($O & 0666) )) ||
11783                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11784
11785                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11786                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11787                 (( $S == ($O & 0666) )) ||
11788                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11789                 rm -f $DIR/$tfile.[smp]$0
11790                 } &
11791                 local pid=$!
11792
11793                 # limit the concurrently running threads to 64. LU-11878
11794                 local idx=$((U % 64))
11795                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11796                 pids[idx]=$pid
11797         done
11798         wait
11799 }
11800 run_test 103b "umask lfs setstripe"
11801
11802 test_103c() {
11803         mkdir -p $DIR/$tdir
11804         cp -rp $DIR/$tdir $DIR/$tdir.bak
11805
11806         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11807                 error "$DIR/$tdir shouldn't contain default ACL"
11808         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11809                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11810         true
11811 }
11812 run_test 103c "'cp -rp' won't set empty acl"
11813
11814 test_103e() {
11815         local numacl
11816         local fileacl
11817         local saved_debug=$($LCTL get_param -n debug)
11818
11819         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11820                 skip "MDS needs to be at least 2.14.52"
11821
11822         large_xattr_enabled || skip_env "ea_inode feature disabled"
11823
11824         mkdir -p $DIR/$tdir
11825         # add big LOV EA to cause reply buffer overflow earlier
11826         $LFS setstripe -C 1000 $DIR/$tdir
11827         lctl set_param mdc.*-mdc*.stats=clear
11828
11829         $LCTL set_param debug=0
11830         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11831         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11832
11833         # add a large number of default ACLs (expect 8000+ for 2.13+)
11834         for U in {2..7000}; do
11835                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11836                         error "Able to add just $U default ACLs"
11837         done
11838         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11839         echo "$numacl default ACLs created"
11840
11841         stat $DIR/$tdir || error "Cannot stat directory"
11842         # check file creation
11843         touch $DIR/$tdir/$tfile ||
11844                 error "failed to create $tfile with $numacl default ACLs"
11845         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11846         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11847         echo "$fileacl ACLs were inherited"
11848         (( $fileacl == $numacl )) ||
11849                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11850         # check that new ACLs creation adds new ACLs to inherited ACLs
11851         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11852                 error "Cannot set new ACL"
11853         numacl=$((numacl + 1))
11854         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11855         (( $fileacl == $numacl )) ||
11856                 error "failed to add new ACL: $fileacl != $numacl as expected"
11857         # adds more ACLs to a file to reach their maximum at 8000+
11858         numacl=0
11859         for U in {20000..25000}; do
11860                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11861                 numacl=$((numacl + 1))
11862         done
11863         echo "Added $numacl more ACLs to the file"
11864         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11865         echo "Total $fileacl ACLs in file"
11866         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11867         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11868         rmdir $DIR/$tdir || error "Cannot remove directory"
11869 }
11870 run_test 103e "inheritance of big amount of default ACLs"
11871
11872 test_103f() {
11873         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11874                 skip "MDS needs to be at least 2.14.51"
11875
11876         large_xattr_enabled || skip_env "ea_inode feature disabled"
11877
11878         # enable changelog to consume more internal MDD buffers
11879         changelog_register
11880
11881         mkdir -p $DIR/$tdir
11882         # add big LOV EA
11883         $LFS setstripe -C 1000 $DIR/$tdir
11884         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11885         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11886         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11887         rmdir $DIR/$tdir || error "Cannot remove directory"
11888 }
11889 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11890
11891 test_104a() {
11892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11893
11894         touch $DIR/$tfile
11895         lfs df || error "lfs df failed"
11896         lfs df -ih || error "lfs df -ih failed"
11897         lfs df -h $DIR || error "lfs df -h $DIR failed"
11898         lfs df -i $DIR || error "lfs df -i $DIR failed"
11899         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11900         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11901
11902         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11903         lctl --device %$OSC deactivate
11904         lfs df || error "lfs df with deactivated OSC failed"
11905         lctl --device %$OSC activate
11906         # wait the osc back to normal
11907         wait_osc_import_ready client ost
11908
11909         lfs df || error "lfs df with reactivated OSC failed"
11910         rm -f $DIR/$tfile
11911 }
11912 run_test 104a "lfs df [-ih] [path] test ========================="
11913
11914 test_104b() {
11915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11916         [ $RUNAS_ID -eq $UID ] &&
11917                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11918
11919         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11920                         grep "Permission denied" | wc -l)))
11921         if [ $denied_cnt -ne 0 ]; then
11922                 error "lfs check servers test failed"
11923         fi
11924 }
11925 run_test 104b "$RUNAS lfs check servers test ===================="
11926
11927 #
11928 # Verify $1 is within range of $2.
11929 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11930 # $1 is <= 2% of $2. Else Fail.
11931 #
11932 value_in_range() {
11933         # Strip all units (M, G, T)
11934         actual=$(echo $1 | tr -d A-Z)
11935         expect=$(echo $2 | tr -d A-Z)
11936
11937         expect_lo=$(($expect * 98 / 100)) # 2% below
11938         expect_hi=$(($expect * 102 / 100)) # 2% above
11939
11940         # permit 2% drift above and below
11941         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11942 }
11943
11944 test_104c() {
11945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11946         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11947
11948         local ost_param="osd-zfs.$FSNAME-OST0000."
11949         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11950         local ofacets=$(get_facets OST)
11951         local mfacets=$(get_facets MDS)
11952         local saved_ost_blocks=
11953         local saved_mdt_blocks=
11954
11955         echo "Before recordsize change"
11956         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11957         df=($(df -h | grep "$MOUNT"$))
11958
11959         # For checking.
11960         echo "lfs output : ${lfs_df[*]}"
11961         echo "df  output : ${df[*]}"
11962
11963         for facet in ${ofacets//,/ }; do
11964                 if [ -z $saved_ost_blocks ]; then
11965                         saved_ost_blocks=$(do_facet $facet \
11966                                 lctl get_param -n $ost_param.blocksize)
11967                         echo "OST Blocksize: $saved_ost_blocks"
11968                 fi
11969                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11970                 do_facet $facet zfs set recordsize=32768 $ost
11971         done
11972
11973         # BS too small. Sufficient for functional testing.
11974         for facet in ${mfacets//,/ }; do
11975                 if [ -z $saved_mdt_blocks ]; then
11976                         saved_mdt_blocks=$(do_facet $facet \
11977                                 lctl get_param -n $mdt_param.blocksize)
11978                         echo "MDT Blocksize: $saved_mdt_blocks"
11979                 fi
11980                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11981                 do_facet $facet zfs set recordsize=32768 $mdt
11982         done
11983
11984         # Give new values chance to reflect change
11985         sleep 2
11986
11987         echo "After recordsize change"
11988         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11989         df_after=($(df -h | grep "$MOUNT"$))
11990
11991         # For checking.
11992         echo "lfs output : ${lfs_df_after[*]}"
11993         echo "df  output : ${df_after[*]}"
11994
11995         # Verify lfs df
11996         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11997                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11998         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11999                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12000         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12001                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12002
12003         # Verify df
12004         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12005                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12006         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12007                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12008         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12009                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12010
12011         # Restore MDT recordize back to original
12012         for facet in ${mfacets//,/ }; do
12013                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12014                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12015         done
12016
12017         # Restore OST recordize back to original
12018         for facet in ${ofacets//,/ }; do
12019                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12020                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12021         done
12022
12023         return 0
12024 }
12025 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12026
12027 test_104d() {
12028         (( $RUNAS_ID != $UID )) ||
12029                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12030
12031         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12032                 skip "lustre version doesn't support lctl dl with non-root"
12033
12034         # debugfs only allows root users to access files, so the
12035         # previous move of the "devices" file to debugfs broke
12036         # "lctl dl" for non-root users. The LU-9680 Netlink
12037         # interface again allows non-root users to list devices.
12038         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12039                 error "lctl dl doesn't work for non root"
12040
12041         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12042         [ "$ost_count" -eq $OSTCOUNT ]  ||
12043                 error "lctl dl reports wrong number of OST devices"
12044
12045         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12046         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12047                 error "lctl dl reports wrong number of MDT devices"
12048 }
12049 run_test 104d "$RUNAS lctl dl test"
12050
12051 test_105a() {
12052         # doesn't work on 2.4 kernels
12053         touch $DIR/$tfile
12054         if $(flock_is_enabled); then
12055                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12056         else
12057                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12058         fi
12059         rm -f $DIR/$tfile
12060 }
12061 run_test 105a "flock when mounted without -o flock test ========"
12062
12063 test_105b() {
12064         touch $DIR/$tfile
12065         if $(flock_is_enabled); then
12066                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12067         else
12068                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12069         fi
12070         rm -f $DIR/$tfile
12071 }
12072 run_test 105b "fcntl when mounted without -o flock test ========"
12073
12074 test_105c() {
12075         touch $DIR/$tfile
12076         if $(flock_is_enabled); then
12077                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12078         else
12079                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12080         fi
12081         rm -f $DIR/$tfile
12082 }
12083 run_test 105c "lockf when mounted without -o flock test"
12084
12085 test_105d() { # bug 15924
12086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12087
12088         test_mkdir $DIR/$tdir
12089         flock_is_enabled || skip_env "mount w/o flock enabled"
12090         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12091         $LCTL set_param fail_loc=0x80000315
12092         flocks_test 2 $DIR/$tdir
12093 }
12094 run_test 105d "flock race (should not freeze) ========"
12095
12096 test_105e() { # bug 22660 && 22040
12097         flock_is_enabled || skip_env "mount w/o flock enabled"
12098
12099         touch $DIR/$tfile
12100         flocks_test 3 $DIR/$tfile
12101 }
12102 run_test 105e "Two conflicting flocks from same process"
12103
12104 test_106() { #bug 10921
12105         test_mkdir $DIR/$tdir
12106         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12107         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12108 }
12109 run_test 106 "attempt exec of dir followed by chown of that dir"
12110
12111 test_107() {
12112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12113
12114         CDIR=`pwd`
12115         local file=core
12116
12117         cd $DIR
12118         rm -f $file
12119
12120         local save_pattern=$(sysctl -n kernel.core_pattern)
12121         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12122         sysctl -w kernel.core_pattern=$file
12123         sysctl -w kernel.core_uses_pid=0
12124
12125         ulimit -c unlimited
12126         sleep 60 &
12127         SLEEPPID=$!
12128
12129         sleep 1
12130
12131         kill -s 11 $SLEEPPID
12132         wait $SLEEPPID
12133         if [ -e $file ]; then
12134                 size=`stat -c%s $file`
12135                 [ $size -eq 0 ] && error "Fail to create core file $file"
12136         else
12137                 error "Fail to create core file $file"
12138         fi
12139         rm -f $file
12140         sysctl -w kernel.core_pattern=$save_pattern
12141         sysctl -w kernel.core_uses_pid=$save_uses_pid
12142         cd $CDIR
12143 }
12144 run_test 107 "Coredump on SIG"
12145
12146 test_110() {
12147         test_mkdir $DIR/$tdir
12148         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12149         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12150                 error "mkdir with 256 char should fail, but did not"
12151         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12152                 error "create with 255 char failed"
12153         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12154                 error "create with 256 char should fail, but did not"
12155
12156         ls -l $DIR/$tdir
12157         rm -rf $DIR/$tdir
12158 }
12159 run_test 110 "filename length checking"
12160
12161 #
12162 # Purpose: To verify dynamic thread (OSS) creation.
12163 #
12164 test_115() {
12165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12166         remote_ost_nodsh && skip "remote OST with nodsh"
12167
12168         # Lustre does not stop service threads once they are started.
12169         # Reset number of running threads to default.
12170         stopall
12171         setupall
12172
12173         local OSTIO_pre
12174         local save_params="$TMP/sanity-$TESTNAME.parameters"
12175
12176         # Get ll_ost_io count before I/O
12177         OSTIO_pre=$(do_facet ost1 \
12178                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12179         # Exit if lustre is not running (ll_ost_io not running).
12180         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12181
12182         echo "Starting with $OSTIO_pre threads"
12183         local thread_max=$((OSTIO_pre * 2))
12184         local rpc_in_flight=$((thread_max * 2))
12185         # this is limited to OSC_MAX_RIF_MAX (256)
12186         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12187         thread_max=$((rpc_in_flight / 2))
12188         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12189                 return
12190
12191         # Number of I/O Process proposed to be started.
12192         local nfiles
12193         local facets=$(get_facets OST)
12194
12195         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12196         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12197
12198         # Set in_flight to $rpc_in_flight
12199         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12200                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12201         nfiles=${rpc_in_flight}
12202         # Set ost thread_max to $thread_max
12203         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12204
12205         # 5 Minutes should be sufficient for max number of OSS
12206         # threads(thread_max) to be created.
12207         local timeout=300
12208
12209         # Start I/O.
12210         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12211         test_mkdir $DIR/$tdir
12212         for i in $(seq $nfiles); do
12213                 local file=$DIR/$tdir/${tfile}-$i
12214                 $LFS setstripe -c -1 -i 0 $file
12215                 ($WTL $file $timeout)&
12216         done
12217
12218         # I/O Started - Wait for thread_started to reach thread_max or report
12219         # error if thread_started is more than thread_max.
12220         echo "Waiting for thread_started to reach thread_max"
12221         local thread_started=0
12222         local end_time=$((SECONDS + timeout))
12223
12224         while [ $SECONDS -le $end_time ] ; do
12225                 echo -n "."
12226                 # Get ost i/o thread_started count.
12227                 thread_started=$(do_facet ost1 \
12228                         "$LCTL get_param \
12229                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12230                 # Break out if thread_started is equal/greater than thread_max
12231                 if [[ $thread_started -ge $thread_max ]]; then
12232                         echo ll_ost_io thread_started $thread_started, \
12233                                 equal/greater than thread_max $thread_max
12234                         break
12235                 fi
12236                 sleep 1
12237         done
12238
12239         # Cleanup - We have the numbers, Kill i/o jobs if running.
12240         jobcount=($(jobs -p))
12241         for i in $(seq 0 $((${#jobcount[@]}-1)))
12242         do
12243                 kill -9 ${jobcount[$i]}
12244                 if [ $? -ne 0 ] ; then
12245                         echo Warning: \
12246                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12247                 fi
12248         done
12249
12250         # Cleanup files left by WTL binary.
12251         for i in $(seq $nfiles); do
12252                 local file=$DIR/$tdir/${tfile}-$i
12253                 rm -rf $file
12254                 if [ $? -ne 0 ] ; then
12255                         echo "Warning: Failed to delete file $file"
12256                 fi
12257         done
12258
12259         restore_lustre_params <$save_params
12260         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12261
12262         # Error out if no new thread has started or Thread started is greater
12263         # than thread max.
12264         if [[ $thread_started -le $OSTIO_pre ||
12265                         $thread_started -gt $thread_max ]]; then
12266                 error "ll_ost_io: thread_started $thread_started" \
12267                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12268                       "No new thread started or thread started greater " \
12269                       "than thread_max."
12270         fi
12271 }
12272 run_test 115 "verify dynamic thread creation===================="
12273
12274 test_116a() { # was previously test_116()
12275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12277         remote_mds_nodsh && skip "remote MDS with nodsh"
12278
12279         echo -n "Free space priority "
12280         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12281                 head -n1
12282         declare -a AVAIL
12283         free_min_max
12284
12285         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12286         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12287         stack_trap simple_cleanup_common
12288
12289         # Check if we need to generate uneven OSTs
12290         test_mkdir -p $DIR/$tdir/OST${MINI}
12291         local FILL=$((MINV / 4))
12292         local DIFF=$((MAXV - MINV))
12293         local DIFF2=$((DIFF * 100 / MINV))
12294
12295         local threshold=$(do_facet $SINGLEMDS \
12296                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12297         threshold=${threshold%%%}
12298         echo -n "Check for uneven OSTs: "
12299         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12300
12301         if [[ $DIFF2 -gt $threshold ]]; then
12302                 echo "ok"
12303                 echo "Don't need to fill OST$MINI"
12304         else
12305                 # generate uneven OSTs. Write 2% over the QOS threshold value
12306                 echo "no"
12307                 DIFF=$((threshold - DIFF2 + 2))
12308                 DIFF2=$((MINV * DIFF / 100))
12309                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12310                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12311                         error "setstripe failed"
12312                 DIFF=$((DIFF2 / 2048))
12313                 i=0
12314                 while [ $i -lt $DIFF ]; do
12315                         i=$((i + 1))
12316                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12317                                 bs=2M count=1 2>/dev/null
12318                         echo -n .
12319                 done
12320                 echo .
12321                 sync
12322                 sleep_maxage
12323                 free_min_max
12324         fi
12325
12326         DIFF=$((MAXV - MINV))
12327         DIFF2=$((DIFF * 100 / MINV))
12328         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12329         if [ $DIFF2 -gt $threshold ]; then
12330                 echo "ok"
12331         else
12332                 skip "QOS imbalance criteria not met"
12333         fi
12334
12335         MINI1=$MINI
12336         MINV1=$MINV
12337         MAXI1=$MAXI
12338         MAXV1=$MAXV
12339
12340         # now fill using QOS
12341         $LFS setstripe -c 1 $DIR/$tdir
12342         FILL=$((FILL / 200))
12343         if [ $FILL -gt 600 ]; then
12344                 FILL=600
12345         fi
12346         echo "writing $FILL files to QOS-assigned OSTs"
12347         i=0
12348         while [ $i -lt $FILL ]; do
12349                 i=$((i + 1))
12350                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12351                         count=1 2>/dev/null
12352                 echo -n .
12353         done
12354         echo "wrote $i 200k files"
12355         sync
12356         sleep_maxage
12357
12358         echo "Note: free space may not be updated, so measurements might be off"
12359         free_min_max
12360         DIFF2=$((MAXV - MINV))
12361         echo "free space delta: orig $DIFF final $DIFF2"
12362         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12363         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12364         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12365         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12366         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12367         if [[ $DIFF -gt 0 ]]; then
12368                 FILL=$((DIFF2 * 100 / DIFF - 100))
12369                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12370         fi
12371
12372         # Figure out which files were written where
12373         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12374                awk '/'$MINI1': / {print $2; exit}')
12375         echo $UUID
12376         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12377         echo "$MINC files created on smaller OST $MINI1"
12378         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12379                awk '/'$MAXI1': / {print $2; exit}')
12380         echo $UUID
12381         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12382         echo "$MAXC files created on larger OST $MAXI1"
12383         if [[ $MINC -gt 0 ]]; then
12384                 FILL=$((MAXC * 100 / MINC - 100))
12385                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12386         fi
12387         [[ $MAXC -gt $MINC ]] ||
12388                 error_ignore LU-9 "stripe QOS didn't balance free space"
12389 }
12390 run_test 116a "stripe QOS: free space balance ==================="
12391
12392 test_116b() { # LU-2093
12393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12394         remote_mds_nodsh && skip "remote MDS with nodsh"
12395
12396 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12397         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12398                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12399         [ -z "$old_rr" ] && skip "no QOS"
12400         do_facet $SINGLEMDS lctl set_param \
12401                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12402         mkdir -p $DIR/$tdir
12403         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12404         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12405         do_facet $SINGLEMDS lctl set_param fail_loc=0
12406         rm -rf $DIR/$tdir
12407         do_facet $SINGLEMDS lctl set_param \
12408                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12409 }
12410 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12411
12412 test_117() # bug 10891
12413 {
12414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12415
12416         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12417         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12418         lctl set_param fail_loc=0x21e
12419         > $DIR/$tfile || error "truncate failed"
12420         lctl set_param fail_loc=0
12421         echo "Truncate succeeded."
12422         rm -f $DIR/$tfile
12423 }
12424 run_test 117 "verify osd extend =========="
12425
12426 NO_SLOW_RESENDCOUNT=4
12427 export OLD_RESENDCOUNT=""
12428 set_resend_count () {
12429         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12430         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12431         lctl set_param -n $PROC_RESENDCOUNT $1
12432         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12433 }
12434
12435 # for reduce test_118* time (b=14842)
12436 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12437
12438 # Reset async IO behavior after error case
12439 reset_async() {
12440         FILE=$DIR/reset_async
12441
12442         # Ensure all OSCs are cleared
12443         $LFS setstripe -c -1 $FILE
12444         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12445         sync
12446         rm $FILE
12447 }
12448
12449 test_118a() #bug 11710
12450 {
12451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12452
12453         reset_async
12454
12455         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12458
12459         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12460                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12461                 return 1;
12462         fi
12463         rm -f $DIR/$tfile
12464 }
12465 run_test 118a "verify O_SYNC works =========="
12466
12467 test_118b()
12468 {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470         remote_ost_nodsh && skip "remote OST with nodsh"
12471
12472         reset_async
12473
12474         #define OBD_FAIL_SRV_ENOENT 0x217
12475         set_nodes_failloc "$(osts_nodes)" 0x217
12476         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12477         RC=$?
12478         set_nodes_failloc "$(osts_nodes)" 0
12479         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12480         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12481                     grep -c writeback)
12482
12483         if [[ $RC -eq 0 ]]; then
12484                 error "Must return error due to dropped pages, rc=$RC"
12485                 return 1;
12486         fi
12487
12488         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12489                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12490                 return 1;
12491         fi
12492
12493         echo "Dirty pages not leaked on ENOENT"
12494
12495         # Due to the above error the OSC will issue all RPCs syncronously
12496         # until a subsequent RPC completes successfully without error.
12497         $MULTIOP $DIR/$tfile Ow4096yc
12498         rm -f $DIR/$tfile
12499
12500         return 0
12501 }
12502 run_test 118b "Reclaim dirty pages on fatal error =========="
12503
12504 test_118c()
12505 {
12506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12507
12508         # for 118c, restore the original resend count, LU-1940
12509         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12510                                 set_resend_count $OLD_RESENDCOUNT
12511         remote_ost_nodsh && skip "remote OST with nodsh"
12512
12513         reset_async
12514
12515         #define OBD_FAIL_OST_EROFS               0x216
12516         set_nodes_failloc "$(osts_nodes)" 0x216
12517
12518         # multiop should block due to fsync until pages are written
12519         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12520         MULTIPID=$!
12521         sleep 1
12522
12523         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12524                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12525         fi
12526
12527         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12528                     grep -c writeback)
12529         if [[ $WRITEBACK -eq 0 ]]; then
12530                 error "No page in writeback, writeback=$WRITEBACK"
12531         fi
12532
12533         set_nodes_failloc "$(osts_nodes)" 0
12534         wait $MULTIPID
12535         RC=$?
12536         if [[ $RC -ne 0 ]]; then
12537                 error "Multiop fsync failed, rc=$RC"
12538         fi
12539
12540         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12541         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12542                     grep -c writeback)
12543         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12544                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12545         fi
12546
12547         rm -f $DIR/$tfile
12548         echo "Dirty pages flushed via fsync on EROFS"
12549         return 0
12550 }
12551 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12552
12553 # continue to use small resend count to reduce test_118* time (b=14842)
12554 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12555
12556 test_118d()
12557 {
12558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12559         remote_ost_nodsh && skip "remote OST with nodsh"
12560
12561         reset_async
12562
12563         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12564         set_nodes_failloc "$(osts_nodes)" 0x214
12565         # multiop should block due to fsync until pages are written
12566         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12567         MULTIPID=$!
12568         sleep 1
12569
12570         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12571                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12572         fi
12573
12574         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12575                     grep -c writeback)
12576         if [[ $WRITEBACK -eq 0 ]]; then
12577                 error "No page in writeback, writeback=$WRITEBACK"
12578         fi
12579
12580         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12581         set_nodes_failloc "$(osts_nodes)" 0
12582
12583         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12584         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12585                     grep -c writeback)
12586         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12587                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12588         fi
12589
12590         rm -f $DIR/$tfile
12591         echo "Dirty pages gaurenteed flushed via fsync"
12592         return 0
12593 }
12594 run_test 118d "Fsync validation inject a delay of the bulk =========="
12595
12596 test_118f() {
12597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12598
12599         reset_async
12600
12601         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12602         lctl set_param fail_loc=0x8000040a
12603
12604         # Should simulate EINVAL error which is fatal
12605         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12606         RC=$?
12607         if [[ $RC -eq 0 ]]; then
12608                 error "Must return error due to dropped pages, rc=$RC"
12609         fi
12610
12611         lctl set_param fail_loc=0x0
12612
12613         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12614         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12615         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12616                     grep -c writeback)
12617         if [[ $LOCKED -ne 0 ]]; then
12618                 error "Locked pages remain in cache, locked=$LOCKED"
12619         fi
12620
12621         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12622                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12623         fi
12624
12625         rm -f $DIR/$tfile
12626         echo "No pages locked after fsync"
12627
12628         reset_async
12629         return 0
12630 }
12631 run_test 118f "Simulate unrecoverable OSC side error =========="
12632
12633 test_118g() {
12634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12635
12636         reset_async
12637
12638         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12639         lctl set_param fail_loc=0x406
12640
12641         # simulate local -ENOMEM
12642         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12643         RC=$?
12644
12645         lctl set_param fail_loc=0
12646         if [[ $RC -eq 0 ]]; then
12647                 error "Must return error due to dropped pages, rc=$RC"
12648         fi
12649
12650         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12651         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12652         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12653                         grep -c writeback)
12654         if [[ $LOCKED -ne 0 ]]; then
12655                 error "Locked pages remain in cache, locked=$LOCKED"
12656         fi
12657
12658         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12659                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12660         fi
12661
12662         rm -f $DIR/$tfile
12663         echo "No pages locked after fsync"
12664
12665         reset_async
12666         return 0
12667 }
12668 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12669
12670 test_118h() {
12671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12672         remote_ost_nodsh && skip "remote OST with nodsh"
12673
12674         reset_async
12675
12676         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12677         set_nodes_failloc "$(osts_nodes)" 0x20e
12678         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12679         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12680         RC=$?
12681
12682         set_nodes_failloc "$(osts_nodes)" 0
12683         if [[ $RC -eq 0 ]]; then
12684                 error "Must return error due to dropped pages, rc=$RC"
12685         fi
12686
12687         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12688         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12689         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12690                     grep -c writeback)
12691         if [[ $LOCKED -ne 0 ]]; then
12692                 error "Locked pages remain in cache, locked=$LOCKED"
12693         fi
12694
12695         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12696                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12697         fi
12698
12699         rm -f $DIR/$tfile
12700         echo "No pages locked after fsync"
12701
12702         return 0
12703 }
12704 run_test 118h "Verify timeout in handling recoverables errors  =========="
12705
12706 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12707
12708 test_118i() {
12709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12710         remote_ost_nodsh && skip "remote OST with nodsh"
12711
12712         reset_async
12713
12714         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12715         set_nodes_failloc "$(osts_nodes)" 0x20e
12716
12717         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12718         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12719         PID=$!
12720         sleep 5
12721         set_nodes_failloc "$(osts_nodes)" 0
12722
12723         wait $PID
12724         RC=$?
12725         if [[ $RC -ne 0 ]]; then
12726                 error "got error, but should be not, rc=$RC"
12727         fi
12728
12729         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12730         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12731         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12732         if [[ $LOCKED -ne 0 ]]; then
12733                 error "Locked pages remain in cache, locked=$LOCKED"
12734         fi
12735
12736         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12737                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12738         fi
12739
12740         rm -f $DIR/$tfile
12741         echo "No pages locked after fsync"
12742
12743         return 0
12744 }
12745 run_test 118i "Fix error before timeout in recoverable error  =========="
12746
12747 [ "$SLOW" = "no" ] && set_resend_count 4
12748
12749 test_118j() {
12750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12751         remote_ost_nodsh && skip "remote OST with nodsh"
12752
12753         reset_async
12754
12755         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12756         set_nodes_failloc "$(osts_nodes)" 0x220
12757
12758         # return -EIO from OST
12759         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12760         RC=$?
12761         set_nodes_failloc "$(osts_nodes)" 0x0
12762         if [[ $RC -eq 0 ]]; then
12763                 error "Must return error due to dropped pages, rc=$RC"
12764         fi
12765
12766         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12767         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12768         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12769         if [[ $LOCKED -ne 0 ]]; then
12770                 error "Locked pages remain in cache, locked=$LOCKED"
12771         fi
12772
12773         # in recoverable error on OST we want resend and stay until it finished
12774         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12775                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12776         fi
12777
12778         rm -f $DIR/$tfile
12779         echo "No pages locked after fsync"
12780
12781         return 0
12782 }
12783 run_test 118j "Simulate unrecoverable OST side error =========="
12784
12785 test_118k()
12786 {
12787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12788         remote_ost_nodsh && skip "remote OSTs with nodsh"
12789
12790         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12791         set_nodes_failloc "$(osts_nodes)" 0x20e
12792         test_mkdir $DIR/$tdir
12793
12794         for ((i=0;i<10;i++)); do
12795                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12796                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12797                 SLEEPPID=$!
12798                 sleep 0.500s
12799                 kill $SLEEPPID
12800                 wait $SLEEPPID
12801         done
12802
12803         set_nodes_failloc "$(osts_nodes)" 0
12804         rm -rf $DIR/$tdir
12805 }
12806 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12807
12808 test_118l() # LU-646
12809 {
12810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12811
12812         test_mkdir $DIR/$tdir
12813         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12814         rm -rf $DIR/$tdir
12815 }
12816 run_test 118l "fsync dir"
12817
12818 test_118m() # LU-3066
12819 {
12820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12821
12822         test_mkdir $DIR/$tdir
12823         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12824         rm -rf $DIR/$tdir
12825 }
12826 run_test 118m "fdatasync dir ========="
12827
12828 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12829
12830 test_118n()
12831 {
12832         local begin
12833         local end
12834
12835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12836         remote_ost_nodsh && skip "remote OSTs with nodsh"
12837
12838         # Sleep to avoid a cached response.
12839         #define OBD_STATFS_CACHE_SECONDS 1
12840         sleep 2
12841
12842         # Inject a 10 second delay in the OST_STATFS handler.
12843         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12844         set_nodes_failloc "$(osts_nodes)" 0x242
12845
12846         begin=$SECONDS
12847         stat --file-system $MOUNT > /dev/null
12848         end=$SECONDS
12849
12850         set_nodes_failloc "$(osts_nodes)" 0
12851
12852         if ((end - begin > 20)); then
12853             error "statfs took $((end - begin)) seconds, expected 10"
12854         fi
12855 }
12856 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12857
12858 test_119a() # bug 11737
12859 {
12860         BSIZE=$((512 * 1024))
12861         directio write $DIR/$tfile 0 1 $BSIZE
12862         # We ask to read two blocks, which is more than a file size.
12863         # directio will indicate an error when requested and actual
12864         # sizes aren't equeal (a normal situation in this case) and
12865         # print actual read amount.
12866         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12867         if [ "$NOB" != "$BSIZE" ]; then
12868                 error "read $NOB bytes instead of $BSIZE"
12869         fi
12870         rm -f $DIR/$tfile
12871 }
12872 run_test 119a "Short directIO read must return actual read amount"
12873
12874 test_119b() # bug 11737
12875 {
12876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12877
12878         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12879         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12880         sync
12881         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12882                 error "direct read failed"
12883         rm -f $DIR/$tfile
12884 }
12885 run_test 119b "Sparse directIO read must return actual read amount"
12886
12887 test_119c() # bug 13099
12888 {
12889         BSIZE=1048576
12890         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12891         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12892         rm -f $DIR/$tfile
12893 }
12894 run_test 119c "Testing for direct read hitting hole"
12895
12896 test_119d() # bug 15950
12897 {
12898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12899
12900         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12901         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12902         BSIZE=1048576
12903         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12904         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12905         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12906         lctl set_param fail_loc=0x40d
12907         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12908         pid_dio=$!
12909         sleep 1
12910         cat $DIR/$tfile > /dev/null &
12911         lctl set_param fail_loc=0
12912         pid_reads=$!
12913         wait $pid_dio
12914         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12915         sleep 2
12916         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12917         error "the read rpcs have not completed in 2s"
12918         rm -f $DIR/$tfile
12919         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12920 }
12921 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12922
12923 test_120a() {
12924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12925         remote_mds_nodsh && skip "remote MDS with nodsh"
12926         test_mkdir -i0 -c1 $DIR/$tdir
12927         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12928                 skip_env "no early lock cancel on server"
12929
12930         lru_resize_disable mdc
12931         lru_resize_disable osc
12932         cancel_lru_locks mdc
12933         # asynchronous object destroy at MDT could cause bl ast to client
12934         cancel_lru_locks osc
12935
12936         stat $DIR/$tdir > /dev/null
12937         can1=$(do_facet mds1 \
12938                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12939                awk '/ldlm_cancel/ {print $2}')
12940         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12941                awk '/ldlm_bl_callback/ {print $2}')
12942         test_mkdir -i0 -c1 $DIR/$tdir/d1
12943         can2=$(do_facet mds1 \
12944                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12945                awk '/ldlm_cancel/ {print $2}')
12946         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12947                awk '/ldlm_bl_callback/ {print $2}')
12948         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12949         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12950         lru_resize_enable mdc
12951         lru_resize_enable osc
12952 }
12953 run_test 120a "Early Lock Cancel: mkdir test"
12954
12955 test_120b() {
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957         remote_mds_nodsh && skip "remote MDS with nodsh"
12958         test_mkdir $DIR/$tdir
12959         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12960                 skip_env "no early lock cancel on server"
12961
12962         lru_resize_disable mdc
12963         lru_resize_disable osc
12964         cancel_lru_locks mdc
12965         stat $DIR/$tdir > /dev/null
12966         can1=$(do_facet $SINGLEMDS \
12967                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12968                awk '/ldlm_cancel/ {print $2}')
12969         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12970                awk '/ldlm_bl_callback/ {print $2}')
12971         touch $DIR/$tdir/f1
12972         can2=$(do_facet $SINGLEMDS \
12973                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12974                awk '/ldlm_cancel/ {print $2}')
12975         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12976                awk '/ldlm_bl_callback/ {print $2}')
12977         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12978         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12979         lru_resize_enable mdc
12980         lru_resize_enable osc
12981 }
12982 run_test 120b "Early Lock Cancel: create test"
12983
12984 test_120c() {
12985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12986         remote_mds_nodsh && skip "remote MDS with nodsh"
12987         test_mkdir -i0 -c1 $DIR/$tdir
12988         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12989                 skip "no early lock cancel on server"
12990
12991         lru_resize_disable mdc
12992         lru_resize_disable osc
12993         test_mkdir -i0 -c1 $DIR/$tdir/d1
12994         test_mkdir -i0 -c1 $DIR/$tdir/d2
12995         touch $DIR/$tdir/d1/f1
12996         cancel_lru_locks mdc
12997         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12998         can1=$(do_facet mds1 \
12999                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13000                awk '/ldlm_cancel/ {print $2}')
13001         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13002                awk '/ldlm_bl_callback/ {print $2}')
13003         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13004         can2=$(do_facet mds1 \
13005                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13006                awk '/ldlm_cancel/ {print $2}')
13007         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13008                awk '/ldlm_bl_callback/ {print $2}')
13009         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13010         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13011         lru_resize_enable mdc
13012         lru_resize_enable osc
13013 }
13014 run_test 120c "Early Lock Cancel: link test"
13015
13016 test_120d() {
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018         remote_mds_nodsh && skip "remote MDS with nodsh"
13019         test_mkdir -i0 -c1 $DIR/$tdir
13020         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13021                 skip_env "no early lock cancel on server"
13022
13023         lru_resize_disable mdc
13024         lru_resize_disable osc
13025         touch $DIR/$tdir
13026         cancel_lru_locks mdc
13027         stat $DIR/$tdir > /dev/null
13028         can1=$(do_facet mds1 \
13029                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13030                awk '/ldlm_cancel/ {print $2}')
13031         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13032                awk '/ldlm_bl_callback/ {print $2}')
13033         chmod a+x $DIR/$tdir
13034         can2=$(do_facet mds1 \
13035                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13036                awk '/ldlm_cancel/ {print $2}')
13037         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13038                awk '/ldlm_bl_callback/ {print $2}')
13039         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13040         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13041         lru_resize_enable mdc
13042         lru_resize_enable osc
13043 }
13044 run_test 120d "Early Lock Cancel: setattr test"
13045
13046 test_120e() {
13047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13048         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13049                 skip_env "no early lock cancel on server"
13050         remote_mds_nodsh && skip "remote MDS with nodsh"
13051
13052         local dlmtrace_set=false
13053
13054         test_mkdir -i0 -c1 $DIR/$tdir
13055         lru_resize_disable mdc
13056         lru_resize_disable osc
13057         ! $LCTL get_param debug | grep -q dlmtrace &&
13058                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13059         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13060         cancel_lru_locks mdc
13061         cancel_lru_locks osc
13062         dd if=$DIR/$tdir/f1 of=/dev/null
13063         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13064         # XXX client can not do early lock cancel of OST lock
13065         # during unlink (LU-4206), so cancel osc lock now.
13066         sleep 2
13067         cancel_lru_locks osc
13068         can1=$(do_facet mds1 \
13069                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13070                awk '/ldlm_cancel/ {print $2}')
13071         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13072                awk '/ldlm_bl_callback/ {print $2}')
13073         unlink $DIR/$tdir/f1
13074         sleep 5
13075         can2=$(do_facet mds1 \
13076                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13077                awk '/ldlm_cancel/ {print $2}')
13078         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13079                awk '/ldlm_bl_callback/ {print $2}')
13080         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13081                 $LCTL dk $TMP/cancel.debug.txt
13082         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13083                 $LCTL dk $TMP/blocking.debug.txt
13084         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13085         lru_resize_enable mdc
13086         lru_resize_enable osc
13087 }
13088 run_test 120e "Early Lock Cancel: unlink test"
13089
13090 test_120f() {
13091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13092         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13093                 skip_env "no early lock cancel on server"
13094         remote_mds_nodsh && skip "remote MDS with nodsh"
13095
13096         test_mkdir -i0 -c1 $DIR/$tdir
13097         lru_resize_disable mdc
13098         lru_resize_disable osc
13099         test_mkdir -i0 -c1 $DIR/$tdir/d1
13100         test_mkdir -i0 -c1 $DIR/$tdir/d2
13101         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13102         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13103         cancel_lru_locks mdc
13104         cancel_lru_locks osc
13105         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13106         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13107         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13108         # XXX client can not do early lock cancel of OST lock
13109         # during rename (LU-4206), so cancel osc lock now.
13110         sleep 2
13111         cancel_lru_locks osc
13112         can1=$(do_facet mds1 \
13113                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13114                awk '/ldlm_cancel/ {print $2}')
13115         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13116                awk '/ldlm_bl_callback/ {print $2}')
13117         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13118         sleep 5
13119         can2=$(do_facet mds1 \
13120                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13121                awk '/ldlm_cancel/ {print $2}')
13122         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13123                awk '/ldlm_bl_callback/ {print $2}')
13124         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13125         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13126         lru_resize_enable mdc
13127         lru_resize_enable osc
13128 }
13129 run_test 120f "Early Lock Cancel: rename test"
13130
13131 test_120g() {
13132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13133         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13134                 skip_env "no early lock cancel on server"
13135         remote_mds_nodsh && skip "remote MDS with nodsh"
13136
13137         lru_resize_disable mdc
13138         lru_resize_disable osc
13139         count=10000
13140         echo create $count files
13141         test_mkdir $DIR/$tdir
13142         cancel_lru_locks mdc
13143         cancel_lru_locks osc
13144         t0=$(date +%s)
13145
13146         can0=$(do_facet $SINGLEMDS \
13147                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13148                awk '/ldlm_cancel/ {print $2}')
13149         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13150                awk '/ldlm_bl_callback/ {print $2}')
13151         createmany -o $DIR/$tdir/f $count
13152         sync
13153         can1=$(do_facet $SINGLEMDS \
13154                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13155                awk '/ldlm_cancel/ {print $2}')
13156         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13157                awk '/ldlm_bl_callback/ {print $2}')
13158         t1=$(date +%s)
13159         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13160         echo rm $count files
13161         rm -r $DIR/$tdir
13162         sync
13163         can2=$(do_facet $SINGLEMDS \
13164                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13165                awk '/ldlm_cancel/ {print $2}')
13166         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13167                awk '/ldlm_bl_callback/ {print $2}')
13168         t2=$(date +%s)
13169         echo total: $count removes in $((t2-t1))
13170         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13171         sleep 2
13172         # wait for commitment of removal
13173         lru_resize_enable mdc
13174         lru_resize_enable osc
13175 }
13176 run_test 120g "Early Lock Cancel: performance test"
13177
13178 test_121() { #bug #10589
13179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13180
13181         rm -rf $DIR/$tfile
13182         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13183 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13184         lctl set_param fail_loc=0x310
13185         cancel_lru_locks osc > /dev/null
13186         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13187         lctl set_param fail_loc=0
13188         [[ $reads -eq $writes ]] ||
13189                 error "read $reads blocks, must be $writes blocks"
13190 }
13191 run_test 121 "read cancel race ========="
13192
13193 test_123a_base() { # was test 123, statahead(bug 11401)
13194         local lsx="$1"
13195
13196         SLOWOK=0
13197         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13198                 log "testing UP system. Performance may be lower than expected."
13199                 SLOWOK=1
13200         fi
13201         running_in_vm && SLOWOK=1
13202
13203         rm -rf $DIR/$tdir
13204         test_mkdir $DIR/$tdir
13205         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13206         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13207         MULT=10
13208         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13209                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13210
13211                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13212                 lctl set_param -n llite.*.statahead_max 0
13213                 lctl get_param llite.*.statahead_max
13214                 cancel_lru_locks mdc
13215                 cancel_lru_locks osc
13216                 stime=$(date +%s)
13217                 time $lsx $DIR/$tdir | wc -l
13218                 etime=$(date +%s)
13219                 delta=$((etime - stime))
13220                 log "$lsx $i files without statahead: $delta sec"
13221                 lctl set_param llite.*.statahead_max=$max
13222
13223                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13224                          awk '/statahead.wrong:/ { print $NF }')
13225                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13226                 cancel_lru_locks mdc
13227                 cancel_lru_locks osc
13228                 stime=$(date +%s)
13229                 time $lsx $DIR/$tdir | wc -l
13230                 etime=$(date +%s)
13231                 delta_sa=$((etime - stime))
13232                 log "$lsx $i files with statahead: $delta_sa sec"
13233                 lctl get_param -n llite.*.statahead_stats
13234                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13235                          awk '/statahead.wrong:/ { print $NF }')
13236
13237                 [[ $swrong -lt $ewrong ]] &&
13238                         log "statahead was stopped, maybe too many locks held!"
13239                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13240
13241                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13242                         max=$(lctl get_param -n llite.*.statahead_max |
13243                                 head -n 1)
13244                         lctl set_param -n llite.*.statahead_max 0
13245                         lctl get_param llite.*.statahead_max
13246                         cancel_lru_locks mdc
13247                         cancel_lru_locks osc
13248                         stime=$(date +%s)
13249                         time $lsx $DIR/$tdir | wc -l
13250                         etime=$(date +%s)
13251                         delta=$((etime - stime))
13252                         log "$lsx $i files again without statahead: $delta sec"
13253                         lctl set_param llite.*.statahead_max=$max
13254                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13255                                 if [ $SLOWOK -eq 0 ]; then
13256                                         error "$lsx $i files is slower with statahead!"
13257                                 else
13258                                         log "$lsx $i files is slower with statahead!"
13259                                 fi
13260                                 break
13261                         fi
13262                 fi
13263
13264                 [ $delta -gt 20 ] && break
13265                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13266                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13267         done
13268         log "$lsx done"
13269
13270         stime=$(date +%s)
13271         rm -r $DIR/$tdir
13272         sync
13273         etime=$(date +%s)
13274         delta=$((etime - stime))
13275         log "rm -r $DIR/$tdir/: $delta seconds"
13276         log "rm done"
13277         lctl get_param -n llite.*.statahead_stats
13278 }
13279
13280 test_123aa() {
13281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13282
13283         test_123a_base "ls -l"
13284 }
13285 run_test 123aa "verify statahead work"
13286
13287 test_123ab() {
13288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13289
13290         statx_supported || skip_env "Test must be statx() syscall supported"
13291
13292         test_123a_base "$STATX -l"
13293 }
13294 run_test 123ab "verify statahead work by using statx"
13295
13296 test_123ac() {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298
13299         statx_supported || skip_env "Test must be statx() syscall supported"
13300
13301         local rpcs_before
13302         local rpcs_after
13303         local agl_before
13304         local agl_after
13305
13306         cancel_lru_locks $OSC
13307         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13308         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13309                      awk '/agl.total:/ { print $NF }')
13310         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13311         test_123a_base "$STATX --cached=always -D"
13312         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13313                     awk '/agl.total:/ { print $NF }')
13314         [ $agl_before -eq $agl_after ] ||
13315                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13316         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13317         [ $rpcs_after -eq $rpcs_before ] ||
13318                 error "$STATX should not send glimpse RPCs to $OSC"
13319 }
13320 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13321
13322 test_123b () { # statahead(bug 15027)
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324
13325         test_mkdir $DIR/$tdir
13326         createmany -o $DIR/$tdir/$tfile-%d 1000
13327
13328         cancel_lru_locks mdc
13329         cancel_lru_locks osc
13330
13331 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13332         lctl set_param fail_loc=0x80000803
13333         ls -lR $DIR/$tdir > /dev/null
13334         log "ls done"
13335         lctl set_param fail_loc=0x0
13336         lctl get_param -n llite.*.statahead_stats
13337         rm -r $DIR/$tdir
13338         sync
13339
13340 }
13341 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13342
13343 test_123c() {
13344         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13345
13346         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13347         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13348         touch $DIR/$tdir.1/{1..3}
13349         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13350
13351         remount_client $MOUNT
13352
13353         $MULTIOP $DIR/$tdir.0 Q
13354
13355         # let statahead to complete
13356         ls -l $DIR/$tdir.0 > /dev/null
13357
13358         testid=$(echo $TESTNAME | tr '_' ' ')
13359         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13360                 error "statahead warning" || true
13361 }
13362 run_test 123c "Can not initialize inode warning on DNE statahead"
13363
13364 test_123d() {
13365         local num=100
13366         local swrong
13367         local ewrong
13368
13369         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13370         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13371                 error "setdirstripe $DIR/$tdir failed"
13372         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13373         remount_client $MOUNT
13374         $LCTL get_param llite.*.statahead_max
13375         $LCTL set_param llite.*.statahead_stats=0 ||
13376                 error "clear statahead_stats failed"
13377         swrong=$(lctl get_param -n llite.*.statahead_stats |
13378                  awk '/statahead.wrong:/ { print $NF }')
13379         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13380         # wait for statahead thread finished to update hit/miss stats.
13381         sleep 1
13382         $LCTL get_param -n llite.*.statahead_stats
13383         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13384                  awk '/statahead.wrong:/ { print $NF }')
13385         (( $swrong == $ewrong )) ||
13386                 log "statahead was stopped, maybe too many locks held!"
13387 }
13388 run_test 123d "Statahead on striped directories works correctly"
13389
13390 test_124a() {
13391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13392         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13393                 skip_env "no lru resize on server"
13394
13395         local NR=2000
13396
13397         test_mkdir $DIR/$tdir
13398
13399         log "create $NR files at $DIR/$tdir"
13400         createmany -o $DIR/$tdir/f $NR ||
13401                 error "failed to create $NR files in $DIR/$tdir"
13402
13403         cancel_lru_locks mdc
13404         ls -l $DIR/$tdir > /dev/null
13405
13406         local NSDIR=""
13407         local LRU_SIZE=0
13408         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13409                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13410                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13411                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13412                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13413                         log "NSDIR=$NSDIR"
13414                         log "NS=$(basename $NSDIR)"
13415                         break
13416                 fi
13417         done
13418
13419         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13420                 skip "Not enough cached locks created!"
13421         fi
13422         log "LRU=$LRU_SIZE"
13423
13424         local SLEEP=30
13425
13426         # We know that lru resize allows one client to hold $LIMIT locks
13427         # for 10h. After that locks begin to be killed by client.
13428         local MAX_HRS=10
13429         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13430         log "LIMIT=$LIMIT"
13431         if [ $LIMIT -lt $LRU_SIZE ]; then
13432                 skip "Limit is too small $LIMIT"
13433         fi
13434
13435         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13436         # killing locks. Some time was spent for creating locks. This means
13437         # that up to the moment of sleep finish we must have killed some of
13438         # them (10-100 locks). This depends on how fast ther were created.
13439         # Many of them were touched in almost the same moment and thus will
13440         # be killed in groups.
13441         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13442
13443         # Use $LRU_SIZE_B here to take into account real number of locks
13444         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13445         local LRU_SIZE_B=$LRU_SIZE
13446         log "LVF=$LVF"
13447         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13448         log "OLD_LVF=$OLD_LVF"
13449         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13450
13451         # Let's make sure that we really have some margin. Client checks
13452         # cached locks every 10 sec.
13453         SLEEP=$((SLEEP+20))
13454         log "Sleep ${SLEEP} sec"
13455         local SEC=0
13456         while ((SEC<$SLEEP)); do
13457                 echo -n "..."
13458                 sleep 5
13459                 SEC=$((SEC+5))
13460                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13461                 echo -n "$LRU_SIZE"
13462         done
13463         echo ""
13464         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13465         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13466
13467         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13468                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13469                 unlinkmany $DIR/$tdir/f $NR
13470                 return
13471         }
13472
13473         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13474         log "unlink $NR files at $DIR/$tdir"
13475         unlinkmany $DIR/$tdir/f $NR
13476 }
13477 run_test 124a "lru resize ======================================="
13478
13479 get_max_pool_limit()
13480 {
13481         local limit=$($LCTL get_param \
13482                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13483         local max=0
13484         for l in $limit; do
13485                 if [[ $l -gt $max ]]; then
13486                         max=$l
13487                 fi
13488         done
13489         echo $max
13490 }
13491
13492 test_124b() {
13493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13494         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13495                 skip_env "no lru resize on server"
13496
13497         LIMIT=$(get_max_pool_limit)
13498
13499         NR=$(($(default_lru_size)*20))
13500         if [[ $NR -gt $LIMIT ]]; then
13501                 log "Limit lock number by $LIMIT locks"
13502                 NR=$LIMIT
13503         fi
13504
13505         IFree=$(mdsrate_inodes_available)
13506         if [ $IFree -lt $NR ]; then
13507                 log "Limit lock number by $IFree inodes"
13508                 NR=$IFree
13509         fi
13510
13511         lru_resize_disable mdc
13512         test_mkdir -p $DIR/$tdir/disable_lru_resize
13513
13514         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13515         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13516         cancel_lru_locks mdc
13517         stime=`date +%s`
13518         PID=""
13519         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13520         PID="$PID $!"
13521         sleep 2
13522         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13523         PID="$PID $!"
13524         sleep 2
13525         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13526         PID="$PID $!"
13527         wait $PID
13528         etime=`date +%s`
13529         nolruresize_delta=$((etime-stime))
13530         log "ls -la time: $nolruresize_delta seconds"
13531         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13532         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13533
13534         lru_resize_enable mdc
13535         test_mkdir -p $DIR/$tdir/enable_lru_resize
13536
13537         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13538         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13539         cancel_lru_locks mdc
13540         stime=`date +%s`
13541         PID=""
13542         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13543         PID="$PID $!"
13544         sleep 2
13545         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13546         PID="$PID $!"
13547         sleep 2
13548         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13549         PID="$PID $!"
13550         wait $PID
13551         etime=`date +%s`
13552         lruresize_delta=$((etime-stime))
13553         log "ls -la time: $lruresize_delta seconds"
13554         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13555
13556         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13557                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13558         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13559                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13560         else
13561                 log "lru resize performs the same with no lru resize"
13562         fi
13563         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13564 }
13565 run_test 124b "lru resize (performance test) ======================="
13566
13567 test_124c() {
13568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13569         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13570                 skip_env "no lru resize on server"
13571
13572         # cache ununsed locks on client
13573         local nr=100
13574         cancel_lru_locks mdc
13575         test_mkdir $DIR/$tdir
13576         createmany -o $DIR/$tdir/f $nr ||
13577                 error "failed to create $nr files in $DIR/$tdir"
13578         ls -l $DIR/$tdir > /dev/null
13579
13580         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13581         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13582         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13583         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13584         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13585
13586         # set lru_max_age to 1 sec
13587         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13588         echo "sleep $((recalc_p * 2)) seconds..."
13589         sleep $((recalc_p * 2))
13590
13591         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13592         # restore lru_max_age
13593         $LCTL set_param -n $nsdir.lru_max_age $max_age
13594         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13595         unlinkmany $DIR/$tdir/f $nr
13596 }
13597 run_test 124c "LRUR cancel very aged locks"
13598
13599 test_124d() {
13600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13601         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13602                 skip_env "no lru resize on server"
13603
13604         # cache ununsed locks on client
13605         local nr=100
13606
13607         lru_resize_disable mdc
13608         stack_trap "lru_resize_enable mdc" EXIT
13609
13610         cancel_lru_locks mdc
13611
13612         # asynchronous object destroy at MDT could cause bl ast to client
13613         test_mkdir $DIR/$tdir
13614         createmany -o $DIR/$tdir/f $nr ||
13615                 error "failed to create $nr files in $DIR/$tdir"
13616         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13617
13618         ls -l $DIR/$tdir > /dev/null
13619
13620         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13621         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13622         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13623         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13624
13625         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13626
13627         # set lru_max_age to 1 sec
13628         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13629         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13630
13631         echo "sleep $((recalc_p * 2)) seconds..."
13632         sleep $((recalc_p * 2))
13633
13634         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13635
13636         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13637 }
13638 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13639
13640 test_125() { # 13358
13641         $LCTL get_param -n llite.*.client_type | grep -q local ||
13642                 skip "must run as local client"
13643         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13644                 skip_env "must have acl enabled"
13645         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13646
13647         test_mkdir $DIR/$tdir
13648         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13649         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13650                 error "setfacl $DIR/$tdir failed"
13651         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13652 }
13653 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13654
13655 test_126() { # bug 12829/13455
13656         $GSS && skip_env "must run as gss disabled"
13657         $LCTL get_param -n llite.*.client_type | grep -q local ||
13658                 skip "must run as local client"
13659         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13660
13661         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13662         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13663         rm -f $DIR/$tfile
13664         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13665 }
13666 run_test 126 "check that the fsgid provided by the client is taken into account"
13667
13668 test_127a() { # bug 15521
13669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13670         local name count samp unit min max sum sumsq
13671
13672         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13673         echo "stats before reset"
13674         $LCTL get_param osc.*.stats
13675         $LCTL set_param osc.*.stats=0
13676         local fsize=$((2048 * 1024))
13677
13678         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13679         cancel_lru_locks osc
13680         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13681
13682         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13683         stack_trap "rm -f $TMP/$tfile.tmp"
13684         while read name count samp unit min max sum sumsq; do
13685                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13686                 [ ! $min ] && error "Missing min value for $name proc entry"
13687                 eval $name=$count || error "Wrong proc format"
13688
13689                 case $name in
13690                 read_bytes|write_bytes)
13691                         [[ "$unit" =~ "bytes" ]] ||
13692                                 error "unit is not 'bytes': $unit"
13693                         (( $min >= 4096 )) || error "min is too small: $min"
13694                         (( $min <= $fsize )) || error "min is too big: $min"
13695                         (( $max >= 4096 )) || error "max is too small: $max"
13696                         (( $max <= $fsize )) || error "max is too big: $max"
13697                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13698                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13699                                 error "sumsquare is too small: $sumsq"
13700                         (( $sumsq <= $fsize * $fsize )) ||
13701                                 error "sumsquare is too big: $sumsq"
13702                         ;;
13703                 ost_read|ost_write)
13704                         [[ "$unit" =~ "usec" ]] ||
13705                                 error "unit is not 'usec': $unit"
13706                         ;;
13707                 *)      ;;
13708                 esac
13709         done < $DIR/$tfile.tmp
13710
13711         #check that we actually got some stats
13712         [ "$read_bytes" ] || error "Missing read_bytes stats"
13713         [ "$write_bytes" ] || error "Missing write_bytes stats"
13714         [ "$read_bytes" != 0 ] || error "no read done"
13715         [ "$write_bytes" != 0 ] || error "no write done"
13716 }
13717 run_test 127a "verify the client stats are sane"
13718
13719 test_127b() { # bug LU-333
13720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13721         local name count samp unit min max sum sumsq
13722
13723         echo "stats before reset"
13724         $LCTL get_param llite.*.stats
13725         $LCTL set_param llite.*.stats=0
13726
13727         # perform 2 reads and writes so MAX is different from SUM.
13728         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13729         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13730         cancel_lru_locks osc
13731         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13732         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13733
13734         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13735         stack_trap "rm -f $TMP/$tfile.tmp"
13736         while read name count samp unit min max sum sumsq; do
13737                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13738                 eval $name=$count || error "Wrong proc format"
13739
13740                 case $name in
13741                 read_bytes|write_bytes)
13742                         [[ "$unit" =~ "bytes" ]] ||
13743                                 error "unit is not 'bytes': $unit"
13744                         (( $count == 2 )) || error "count is not 2: $count"
13745                         (( $min == $PAGE_SIZE )) ||
13746                                 error "min is not $PAGE_SIZE: $min"
13747                         (( $max == $PAGE_SIZE )) ||
13748                                 error "max is not $PAGE_SIZE: $max"
13749                         (( $sum == $PAGE_SIZE * 2 )) ||
13750                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13751                         ;;
13752                 read|write)
13753                         [[ "$unit" =~ "usec" ]] ||
13754                                 error "unit is not 'usec': $unit"
13755                         ;;
13756                 *)      ;;
13757                 esac
13758         done < $TMP/$tfile.tmp
13759
13760         #check that we actually got some stats
13761         [ "$read_bytes" ] || error "Missing read_bytes stats"
13762         [ "$write_bytes" ] || error "Missing write_bytes stats"
13763         [ "$read_bytes" != 0 ] || error "no read done"
13764         [ "$write_bytes" != 0 ] || error "no write done"
13765 }
13766 run_test 127b "verify the llite client stats are sane"
13767
13768 test_127c() { # LU-12394
13769         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13770         local size
13771         local bsize
13772         local reads
13773         local writes
13774         local count
13775
13776         $LCTL set_param llite.*.extents_stats=1
13777         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13778
13779         # Use two stripes so there is enough space in default config
13780         $LFS setstripe -c 2 $DIR/$tfile
13781
13782         # Extent stats start at 0-4K and go in power of two buckets
13783         # LL_HIST_START = 12 --> 2^12 = 4K
13784         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13785         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13786         # small configs
13787         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13788                 do
13789                 # Write and read, 2x each, second time at a non-zero offset
13790                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13791                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13792                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13793                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13794                 rm -f $DIR/$tfile
13795         done
13796
13797         $LCTL get_param llite.*.extents_stats
13798
13799         count=2
13800         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13801                 do
13802                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13803                                 grep -m 1 $bsize)
13804                 reads=$(echo $bucket | awk '{print $5}')
13805                 writes=$(echo $bucket | awk '{print $9}')
13806                 [ "$reads" -eq $count ] ||
13807                         error "$reads reads in < $bsize bucket, expect $count"
13808                 [ "$writes" -eq $count ] ||
13809                         error "$writes writes in < $bsize bucket, expect $count"
13810         done
13811
13812         # Test mmap write and read
13813         $LCTL set_param llite.*.extents_stats=c
13814         size=512
13815         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13816         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13817         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13818
13819         $LCTL get_param llite.*.extents_stats
13820
13821         count=$(((size*1024) / PAGE_SIZE))
13822
13823         bsize=$((2 * PAGE_SIZE / 1024))K
13824
13825         bucket=$($LCTL get_param -n llite.*.extents_stats |
13826                         grep -m 1 $bsize)
13827         reads=$(echo $bucket | awk '{print $5}')
13828         writes=$(echo $bucket | awk '{print $9}')
13829         # mmap writes fault in the page first, creating an additonal read
13830         [ "$reads" -eq $((2 * count)) ] ||
13831                 error "$reads reads in < $bsize bucket, expect $count"
13832         [ "$writes" -eq $count ] ||
13833                 error "$writes writes in < $bsize bucket, expect $count"
13834 }
13835 run_test 127c "test llite extent stats with regular & mmap i/o"
13836
13837 test_128() { # bug 15212
13838         touch $DIR/$tfile
13839         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13840                 find $DIR/$tfile
13841                 find $DIR/$tfile
13842         EOF
13843
13844         result=$(grep error $TMP/$tfile.log)
13845         rm -f $DIR/$tfile $TMP/$tfile.log
13846         [ -z "$result" ] ||
13847                 error "consecutive find's under interactive lfs failed"
13848 }
13849 run_test 128 "interactive lfs for 2 consecutive find's"
13850
13851 set_dir_limits () {
13852         local mntdev
13853         local canondev
13854         local node
13855
13856         local ldproc=/proc/fs/ldiskfs
13857         local facets=$(get_facets MDS)
13858
13859         for facet in ${facets//,/ }; do
13860                 canondev=$(ldiskfs_canon \
13861                            *.$(convert_facet2label $facet).mntdev $facet)
13862                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13863                         ldproc=/sys/fs/ldiskfs
13864                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13865                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13866         done
13867 }
13868
13869 check_mds_dmesg() {
13870         local facets=$(get_facets MDS)
13871         for facet in ${facets//,/ }; do
13872                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13873         done
13874         return 1
13875 }
13876
13877 test_129() {
13878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13879         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13880                 skip "Need MDS version with at least 2.5.56"
13881         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13882                 skip_env "ldiskfs only test"
13883         fi
13884         remote_mds_nodsh && skip "remote MDS with nodsh"
13885
13886         local ENOSPC=28
13887         local has_warning=false
13888
13889         rm -rf $DIR/$tdir
13890         mkdir -p $DIR/$tdir
13891
13892         # block size of mds1
13893         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13894         set_dir_limits $maxsize $((maxsize * 6 / 8))
13895         stack_trap "set_dir_limits 0 0"
13896         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13897         local dirsize=$(stat -c%s "$DIR/$tdir")
13898         local nfiles=0
13899         while (( $dirsize <= $maxsize )); do
13900                 $MCREATE $DIR/$tdir/file_base_$nfiles
13901                 rc=$?
13902                 # check two errors:
13903                 # ENOSPC for ext4 max_dir_size, which has been used since
13904                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13905                 if (( rc == ENOSPC )); then
13906                         set_dir_limits 0 0
13907                         echo "rc=$rc returned as expected after $nfiles files"
13908
13909                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13910                                 error "create failed w/o dir size limit"
13911
13912                         # messages may be rate limited if test is run repeatedly
13913                         check_mds_dmesg '"is approaching max"' ||
13914                                 echo "warning message should be output"
13915                         check_mds_dmesg '"has reached max"' ||
13916                                 echo "reached message should be output"
13917
13918                         dirsize=$(stat -c%s "$DIR/$tdir")
13919
13920                         [[ $dirsize -ge $maxsize ]] && return 0
13921                         error "dirsize $dirsize < $maxsize after $nfiles files"
13922                 elif (( rc != 0 )); then
13923                         break
13924                 fi
13925                 nfiles=$((nfiles + 1))
13926                 dirsize=$(stat -c%s "$DIR/$tdir")
13927         done
13928
13929         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13930 }
13931 run_test 129 "test directory size limit ========================"
13932
13933 OLDIFS="$IFS"
13934 cleanup_130() {
13935         trap 0
13936         IFS="$OLDIFS"
13937 }
13938
13939 test_130a() {
13940         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13941         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13942
13943         trap cleanup_130 EXIT RETURN
13944
13945         local fm_file=$DIR/$tfile
13946         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13947         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13948                 error "dd failed for $fm_file"
13949
13950         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13951         filefrag -ves $fm_file
13952         local rc=$?
13953         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13954                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13955         (( $rc == 0 )) || error "filefrag $fm_file failed"
13956
13957         filefrag_op=$(filefrag -ve -k $fm_file |
13958                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13959         local lun=$($LFS getstripe -i $fm_file)
13960
13961         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13962         IFS=$'\n'
13963         local tot_len=0
13964         for line in $filefrag_op; do
13965                 local frag_lun=$(echo $line | cut -d: -f5)
13966                 local ext_len=$(echo $line | cut -d: -f4)
13967
13968                 if (( $frag_lun != $lun )); then
13969                         error "FIEMAP on 1-stripe file($fm_file) failed"
13970                         return
13971                 fi
13972                 (( tot_len += ext_len ))
13973         done
13974
13975         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13976                 error "FIEMAP on 1-stripe file($fm_file) failed"
13977                 return
13978         fi
13979
13980         echo "FIEMAP on single striped file succeeded"
13981 }
13982 run_test 130a "FIEMAP (1-stripe file)"
13983
13984 test_130b() {
13985         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13986
13987         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13988         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13989         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13990                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13991
13992         trap cleanup_130 EXIT RETURN
13993
13994         local fm_file=$DIR/$tfile
13995         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13996                 error "setstripe on $fm_file"
13997
13998         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13999                 error "dd failed on $fm_file"
14000
14001         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14002         filefrag_op=$(filefrag -ve -k $fm_file |
14003                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14004
14005         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14006                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14007
14008         IFS=$'\n'
14009         local tot_len=0
14010         local num_luns=1
14011
14012         for line in $filefrag_op; do
14013                 local frag_lun=$(echo $line | cut -d: -f5 |
14014                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14015                 local ext_len=$(echo $line | cut -d: -f4)
14016                 if (( $frag_lun != $last_lun )); then
14017                         if (( tot_len != 1024 )); then
14018                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14019                                 return
14020                         else
14021                                 (( num_luns += 1 ))
14022                                 tot_len=0
14023                         fi
14024                 fi
14025                 (( tot_len += ext_len ))
14026                 last_lun=$frag_lun
14027         done
14028         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14029                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14030                 return
14031         fi
14032
14033         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14034 }
14035 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14036
14037 test_130c() {
14038         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14039
14040         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14041         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14042         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14043                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14044
14045         trap cleanup_130 EXIT RETURN
14046
14047         local fm_file=$DIR/$tfile
14048         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14049
14050         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14051                 error "dd failed on $fm_file"
14052
14053         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14054         filefrag_op=$(filefrag -ve -k $fm_file |
14055                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14056
14057         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14058                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14059
14060         IFS=$'\n'
14061         local tot_len=0
14062         local num_luns=1
14063         for line in $filefrag_op; do
14064                 local frag_lun=$(echo $line | cut -d: -f5 |
14065                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14066                 local ext_len=$(echo $line | cut -d: -f4)
14067                 if (( $frag_lun != $last_lun )); then
14068                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14069                         if (( logical != 512 )); then
14070                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14071                                 return
14072                         fi
14073                         if (( tot_len != 512 )); then
14074                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14075                                 return
14076                         else
14077                                 (( num_luns += 1 ))
14078                                 tot_len=0
14079                         fi
14080                 fi
14081                 (( tot_len += ext_len ))
14082                 last_lun=$frag_lun
14083         done
14084         if (( num_luns != 2 || tot_len != 512 )); then
14085                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14086                 return
14087         fi
14088
14089         echo "FIEMAP on 2-stripe file with hole succeeded"
14090 }
14091 run_test 130c "FIEMAP (2-stripe file with hole)"
14092
14093 test_130d() {
14094         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14095
14096         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14097         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14098         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14099                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14100
14101         trap cleanup_130 EXIT RETURN
14102
14103         local fm_file=$DIR/$tfile
14104         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14105                         error "setstripe on $fm_file"
14106
14107         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14108         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14109                 error "dd failed on $fm_file"
14110
14111         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14112         filefrag_op=$(filefrag -ve -k $fm_file |
14113                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14114
14115         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14116                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14117
14118         IFS=$'\n'
14119         local tot_len=0
14120         local num_luns=1
14121         for line in $filefrag_op; do
14122                 local frag_lun=$(echo $line | cut -d: -f5 |
14123                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14124                 local ext_len=$(echo $line | cut -d: -f4)
14125                 if (( $frag_lun != $last_lun )); then
14126                         if (( tot_len != 1024 )); then
14127                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14128                                 return
14129                         else
14130                                 (( num_luns += 1 ))
14131                                 local tot_len=0
14132                         fi
14133                 fi
14134                 (( tot_len += ext_len ))
14135                 last_lun=$frag_lun
14136         done
14137         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14138                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14139                 return
14140         fi
14141
14142         echo "FIEMAP on N-stripe file succeeded"
14143 }
14144 run_test 130d "FIEMAP (N-stripe file)"
14145
14146 test_130e() {
14147         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14148
14149         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14150         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14151         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14152                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14153
14154         trap cleanup_130 EXIT RETURN
14155
14156         local fm_file=$DIR/$tfile
14157         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14158
14159         local num_blks=512
14160         local expected_len=$(( (num_blks / 2) * 64 ))
14161         for ((i = 0; i < $num_blks; i++)); do
14162                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14163                         conv=notrunc > /dev/null 2>&1
14164         done
14165
14166         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14167         filefrag_op=$(filefrag -ve -k $fm_file |
14168                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14169
14170         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14171
14172         IFS=$'\n'
14173         local tot_len=0
14174         local num_luns=1
14175         for line in $filefrag_op; do
14176                 local frag_lun=$(echo $line | cut -d: -f5)
14177                 local ext_len=$(echo $line | cut -d: -f4)
14178                 if (( $frag_lun != $last_lun )); then
14179                         if (( tot_len != $expected_len )); then
14180                                 error "OST$last_lun $tot_len != $expected_len"
14181                         else
14182                                 (( num_luns += 1 ))
14183                                 tot_len=0
14184                         fi
14185                 fi
14186                 (( tot_len += ext_len ))
14187                 last_lun=$frag_lun
14188         done
14189         if (( num_luns != 2 || tot_len != $expected_len )); then
14190                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14191         fi
14192
14193         echo "FIEMAP with continuation calls succeeded"
14194 }
14195 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14196
14197 test_130f() {
14198         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14199         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14200         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14201                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14202
14203         local fm_file=$DIR/$tfile
14204         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14205                 error "multiop create with lov_delay_create on $fm_file"
14206
14207         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14208         filefrag_extents=$(filefrag -vek $fm_file |
14209                            awk '/extents? found/ { print $2 }')
14210         if (( $filefrag_extents != 0 )); then
14211                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14212         fi
14213
14214         rm -f $fm_file
14215 }
14216 run_test 130f "FIEMAP (unstriped file)"
14217
14218 test_130g() {
14219         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14220                 skip "Need MDS version with at least 2.12.53 for overstriping"
14221         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14222         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14223         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14224                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14225
14226         local file=$DIR/$tfile
14227         local nr=$((OSTCOUNT * 100))
14228
14229         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14230
14231         stack_trap "rm -f $file"
14232         dd if=/dev/zero of=$file count=$nr bs=1M
14233         sync
14234         nr=$($LFS getstripe -c $file)
14235
14236         local extents=$(filefrag -v $file |
14237                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14238
14239         echo "filefrag list $extents extents in file with stripecount $nr"
14240         if (( extents < nr )); then
14241                 $LFS getstripe $file
14242                 filefrag -v $file
14243                 error "filefrag printed $extents < $nr extents"
14244         fi
14245 }
14246 run_test 130g "FIEMAP (overstripe file)"
14247
14248 # Test for writev/readv
14249 test_131a() {
14250         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14251                 error "writev test failed"
14252         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14253                 error "readv failed"
14254         rm -f $DIR/$tfile
14255 }
14256 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14257
14258 test_131b() {
14259         local fsize=$((524288 + 1048576 + 1572864))
14260         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14261                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14262                         error "append writev test failed"
14263
14264         ((fsize += 1572864 + 1048576))
14265         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14266                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14267                         error "append writev test failed"
14268         rm -f $DIR/$tfile
14269 }
14270 run_test 131b "test append writev"
14271
14272 test_131c() {
14273         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14274         error "NOT PASS"
14275 }
14276 run_test 131c "test read/write on file w/o objects"
14277
14278 test_131d() {
14279         rwv -f $DIR/$tfile -w -n 1 1572864
14280         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14281         if [ "$NOB" != 1572864 ]; then
14282                 error "Short read filed: read $NOB bytes instead of 1572864"
14283         fi
14284         rm -f $DIR/$tfile
14285 }
14286 run_test 131d "test short read"
14287
14288 test_131e() {
14289         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14290         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14291         error "read hitting hole failed"
14292         rm -f $DIR/$tfile
14293 }
14294 run_test 131e "test read hitting hole"
14295
14296 check_stats() {
14297         local facet=$1
14298         local op=$2
14299         local want=${3:-0}
14300         local res
14301
14302         # open             11 samples [usecs] 468 4793 13658 35791898
14303         case $facet in
14304         mds*) res=($(do_facet $facet \
14305                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14306                  ;;
14307         ost*) res=($(do_facet $facet \
14308                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14309                  ;;
14310         *) error "Wrong facet '$facet'" ;;
14311         esac
14312         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14313         # if $want is zero, it means any stat increment is ok.
14314         if (( $want > 0 )); then
14315                 local count=${res[1]}
14316
14317                 if (( $count != $want )); then
14318                         if [[ $facet =~ "mds" ]]; then
14319                                 do_nodes $(comma_list $(mdts_nodes)) \
14320                                         $LCTL get_param mdt.*.md_stats
14321                         else
14322                                 do_nodes $(comma_list $(osts-nodes)) \
14323                                         $LCTL get_param obdfilter.*.stats
14324                         fi
14325                         error "The $op counter on $facet is $count, not $want"
14326                 fi
14327         fi
14328 }
14329
14330 test_133a() {
14331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14332         remote_ost_nodsh && skip "remote OST with nodsh"
14333         remote_mds_nodsh && skip "remote MDS with nodsh"
14334         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14335                 skip_env "MDS doesn't support rename stats"
14336
14337         local testdir=$DIR/${tdir}/stats_testdir
14338
14339         mkdir -p $DIR/${tdir}
14340
14341         # clear stats.
14342         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14343         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14344
14345         # verify mdt stats first.
14346         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14347         check_stats $SINGLEMDS "mkdir" 1
14348
14349         # clear "open" from "lfs mkdir" above
14350         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14351         touch ${testdir}/${tfile} || error "touch failed"
14352         check_stats $SINGLEMDS "open" 1
14353         check_stats $SINGLEMDS "close" 1
14354         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14355                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14356                 check_stats $SINGLEMDS "mknod" 2
14357         }
14358         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14359         check_stats $SINGLEMDS "unlink" 1
14360         rm -f ${testdir}/${tfile} || error "file remove failed"
14361         check_stats $SINGLEMDS "unlink" 2
14362
14363         # remove working dir and check mdt stats again.
14364         rmdir ${testdir} || error "rmdir failed"
14365         check_stats $SINGLEMDS "rmdir" 1
14366
14367         local testdir1=$DIR/${tdir}/stats_testdir1
14368         mkdir -p ${testdir}
14369         mkdir -p ${testdir1}
14370         touch ${testdir1}/test1
14371         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14372         check_stats $SINGLEMDS "crossdir_rename" 1
14373
14374         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14375         check_stats $SINGLEMDS "samedir_rename" 1
14376
14377         rm -rf $DIR/${tdir}
14378 }
14379 run_test 133a "Verifying MDT stats ========================================"
14380
14381 test_133b() {
14382         local res
14383
14384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14385         remote_ost_nodsh && skip "remote OST with nodsh"
14386         remote_mds_nodsh && skip "remote MDS with nodsh"
14387
14388         local testdir=$DIR/${tdir}/stats_testdir
14389
14390         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14391         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14392         touch ${testdir}/${tfile} || error "touch failed"
14393         cancel_lru_locks mdc
14394
14395         # clear stats.
14396         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14397         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14398
14399         # extra mdt stats verification.
14400         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14401         check_stats $SINGLEMDS "setattr" 1
14402         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14403         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14404         then            # LU-1740
14405                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14406                 check_stats $SINGLEMDS "getattr" 1
14407         fi
14408         rm -rf $DIR/${tdir}
14409
14410         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14411         # so the check below is not reliable
14412         [ $MDSCOUNT -eq 1 ] || return 0
14413
14414         # Sleep to avoid a cached response.
14415         #define OBD_STATFS_CACHE_SECONDS 1
14416         sleep 2
14417         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14418         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14419         $LFS df || error "lfs failed"
14420         check_stats $SINGLEMDS "statfs" 1
14421
14422         # check aggregated statfs (LU-10018)
14423         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14424                 return 0
14425         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14426                 return 0
14427         sleep 2
14428         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14429         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14430         df $DIR
14431         check_stats $SINGLEMDS "statfs" 1
14432
14433         # We want to check that the client didn't send OST_STATFS to
14434         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14435         # extra care is needed here.
14436         if remote_mds; then
14437                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14438                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14439
14440                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14441                 [ "$res" ] && error "OST got STATFS"
14442         fi
14443
14444         return 0
14445 }
14446 run_test 133b "Verifying extra MDT stats =================================="
14447
14448 test_133c() {
14449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14450         remote_ost_nodsh && skip "remote OST with nodsh"
14451         remote_mds_nodsh && skip "remote MDS with nodsh"
14452
14453         local testdir=$DIR/$tdir/stats_testdir
14454
14455         test_mkdir -p $testdir
14456
14457         # verify obdfilter stats.
14458         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14459         sync
14460         cancel_lru_locks osc
14461         wait_delete_completed
14462
14463         # clear stats.
14464         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14465         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14466
14467         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14468                 error "dd failed"
14469         sync
14470         cancel_lru_locks osc
14471         check_stats ost1 "write" 1
14472
14473         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14474         check_stats ost1 "read" 1
14475
14476         > $testdir/$tfile || error "truncate failed"
14477         check_stats ost1 "punch" 1
14478
14479         rm -f $testdir/$tfile || error "file remove failed"
14480         wait_delete_completed
14481         check_stats ost1 "destroy" 1
14482
14483         rm -rf $DIR/$tdir
14484 }
14485 run_test 133c "Verifying OST stats ========================================"
14486
14487 order_2() {
14488         local value=$1
14489         local orig=$value
14490         local order=1
14491
14492         while [ $value -ge 2 ]; do
14493                 order=$((order*2))
14494                 value=$((value/2))
14495         done
14496
14497         if [ $orig -gt $order ]; then
14498                 order=$((order*2))
14499         fi
14500         echo $order
14501 }
14502
14503 size_in_KMGT() {
14504     local value=$1
14505     local size=('K' 'M' 'G' 'T');
14506     local i=0
14507     local size_string=$value
14508
14509     while [ $value -ge 1024 ]; do
14510         if [ $i -gt 3 ]; then
14511             #T is the biggest unit we get here, if that is bigger,
14512             #just return XXXT
14513             size_string=${value}T
14514             break
14515         fi
14516         value=$((value >> 10))
14517         if [ $value -lt 1024 ]; then
14518             size_string=${value}${size[$i]}
14519             break
14520         fi
14521         i=$((i + 1))
14522     done
14523
14524     echo $size_string
14525 }
14526
14527 get_rename_size() {
14528         local size=$1
14529         local context=${2:-.}
14530         local sample=$(do_facet $SINGLEMDS $LCTL \
14531                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14532                 grep -A1 $context |
14533                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14534         echo $sample
14535 }
14536
14537 test_133d() {
14538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14539         remote_ost_nodsh && skip "remote OST with nodsh"
14540         remote_mds_nodsh && skip "remote MDS with nodsh"
14541         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14542                 skip_env "MDS doesn't support rename stats"
14543
14544         local testdir1=$DIR/${tdir}/stats_testdir1
14545         local testdir2=$DIR/${tdir}/stats_testdir2
14546         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14547
14548         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14549
14550         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14551         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14552
14553         createmany -o $testdir1/test 512 || error "createmany failed"
14554
14555         # check samedir rename size
14556         mv ${testdir1}/test0 ${testdir1}/test_0
14557
14558         local testdir1_size=$(ls -l $DIR/${tdir} |
14559                 awk '/stats_testdir1/ {print $5}')
14560         local testdir2_size=$(ls -l $DIR/${tdir} |
14561                 awk '/stats_testdir2/ {print $5}')
14562
14563         testdir1_size=$(order_2 $testdir1_size)
14564         testdir2_size=$(order_2 $testdir2_size)
14565
14566         testdir1_size=$(size_in_KMGT $testdir1_size)
14567         testdir2_size=$(size_in_KMGT $testdir2_size)
14568
14569         echo "source rename dir size: ${testdir1_size}"
14570         echo "target rename dir size: ${testdir2_size}"
14571
14572         local cmd="do_facet $SINGLEMDS $LCTL "
14573         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14574
14575         eval $cmd || error "$cmd failed"
14576         local samedir=$($cmd | grep 'same_dir')
14577         local same_sample=$(get_rename_size $testdir1_size)
14578         [ -z "$samedir" ] && error "samedir_rename_size count error"
14579         [[ $same_sample -eq 1 ]] ||
14580                 error "samedir_rename_size error $same_sample"
14581         echo "Check same dir rename stats success"
14582
14583         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14584
14585         # check crossdir rename size
14586         mv ${testdir1}/test_0 ${testdir2}/test_0
14587
14588         testdir1_size=$(ls -l $DIR/${tdir} |
14589                 awk '/stats_testdir1/ {print $5}')
14590         testdir2_size=$(ls -l $DIR/${tdir} |
14591                 awk '/stats_testdir2/ {print $5}')
14592
14593         testdir1_size=$(order_2 $testdir1_size)
14594         testdir2_size=$(order_2 $testdir2_size)
14595
14596         testdir1_size=$(size_in_KMGT $testdir1_size)
14597         testdir2_size=$(size_in_KMGT $testdir2_size)
14598
14599         echo "source rename dir size: ${testdir1_size}"
14600         echo "target rename dir size: ${testdir2_size}"
14601
14602         eval $cmd || error "$cmd failed"
14603         local crossdir=$($cmd | grep 'crossdir')
14604         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14605         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14606         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14607         [[ $src_sample -eq 1 ]] ||
14608                 error "crossdir_rename_size error $src_sample"
14609         [[ $tgt_sample -eq 1 ]] ||
14610                 error "crossdir_rename_size error $tgt_sample"
14611         echo "Check cross dir rename stats success"
14612         rm -rf $DIR/${tdir}
14613 }
14614 run_test 133d "Verifying rename_stats ========================================"
14615
14616 test_133e() {
14617         remote_mds_nodsh && skip "remote MDS with nodsh"
14618         remote_ost_nodsh && skip "remote OST with nodsh"
14619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14620
14621         local testdir=$DIR/${tdir}/stats_testdir
14622         local ctr f0 f1 bs=32768 count=42 sum
14623
14624         mkdir -p ${testdir} || error "mkdir failed"
14625
14626         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14627
14628         for ctr in {write,read}_bytes; do
14629                 sync
14630                 cancel_lru_locks osc
14631
14632                 do_facet ost1 $LCTL set_param -n \
14633                         "obdfilter.*.exports.clear=clear"
14634
14635                 if [ $ctr = write_bytes ]; then
14636                         f0=/dev/zero
14637                         f1=${testdir}/${tfile}
14638                 else
14639                         f0=${testdir}/${tfile}
14640                         f1=/dev/null
14641                 fi
14642
14643                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14644                         error "dd failed"
14645                 sync
14646                 cancel_lru_locks osc
14647
14648                 sum=$(do_facet ost1 $LCTL get_param \
14649                         "obdfilter.*.exports.*.stats" |
14650                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14651                                 $1 == ctr { sum += $7 }
14652                                 END { printf("%0.0f", sum) }')
14653
14654                 if ((sum != bs * count)); then
14655                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14656                 fi
14657         done
14658
14659         rm -rf $DIR/${tdir}
14660 }
14661 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14662
14663 test_133f() {
14664         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14665                 skip "too old lustre for get_param -R ($facet_ver)"
14666
14667         # verifying readability.
14668         $LCTL get_param -R '*' &> /dev/null
14669
14670         # Verifing writability with badarea_io.
14671         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14672         local skipped_params='force_lbug|changelog_mask|daemon_file'
14673         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14674                 egrep -v "$skipped_params" |
14675                 xargs -n 1 find $proc_dirs -name |
14676                 xargs -n 1 badarea_io ||
14677                 error "client badarea_io failed"
14678
14679         # remount the FS in case writes/reads /proc break the FS
14680         cleanup || error "failed to unmount"
14681         setup || error "failed to setup"
14682 }
14683 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14684
14685 test_133g() {
14686         remote_mds_nodsh && skip "remote MDS with nodsh"
14687         remote_ost_nodsh && skip "remote OST with nodsh"
14688
14689         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14690         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14691         local facet
14692         for facet in mds1 ost1; do
14693                 local facet_ver=$(lustre_version_code $facet)
14694                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14695                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14696                 else
14697                         log "$facet: too old lustre for get_param -R"
14698                 fi
14699                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14700                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14701                                 tr -d = | egrep -v $skipped_params |
14702                                 xargs -n 1 find $proc_dirs -name |
14703                                 xargs -n 1 badarea_io" ||
14704                                         error "$facet badarea_io failed"
14705                 else
14706                         skip_noexit "$facet: too old lustre for get_param -R"
14707                 fi
14708         done
14709
14710         # remount the FS in case writes/reads /proc break the FS
14711         cleanup || error "failed to unmount"
14712         setup || error "failed to setup"
14713 }
14714 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14715
14716 test_133h() {
14717         remote_mds_nodsh && skip "remote MDS with nodsh"
14718         remote_ost_nodsh && skip "remote OST with nodsh"
14719         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14720                 skip "Need MDS version at least 2.9.54"
14721
14722         local facet
14723         for facet in client mds1 ost1; do
14724                 # Get the list of files that are missing the terminating newline
14725                 local plist=$(do_facet $facet
14726                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14727                 local ent
14728                 for ent in $plist; do
14729                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14730                                 awk -v FS='\v' -v RS='\v\v' \
14731                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14732                                         print FILENAME}'" 2>/dev/null)
14733                         [ -z $missing ] || {
14734                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14735                                 error "file does not end with newline: $facet-$ent"
14736                         }
14737                 done
14738         done
14739 }
14740 run_test 133h "Proc files should end with newlines"
14741
14742 test_134a() {
14743         remote_mds_nodsh && skip "remote MDS with nodsh"
14744         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14745                 skip "Need MDS version at least 2.7.54"
14746
14747         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14748         cancel_lru_locks mdc
14749
14750         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14751         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14752         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14753
14754         local nr=1000
14755         createmany -o $DIR/$tdir/f $nr ||
14756                 error "failed to create $nr files in $DIR/$tdir"
14757         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14758
14759         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14760         do_facet mds1 $LCTL set_param fail_loc=0x327
14761         do_facet mds1 $LCTL set_param fail_val=500
14762         touch $DIR/$tdir/m
14763
14764         echo "sleep 10 seconds ..."
14765         sleep 10
14766         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14767
14768         do_facet mds1 $LCTL set_param fail_loc=0
14769         do_facet mds1 $LCTL set_param fail_val=0
14770         [ $lck_cnt -lt $unused ] ||
14771                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14772
14773         rm $DIR/$tdir/m
14774         unlinkmany $DIR/$tdir/f $nr
14775 }
14776 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14777
14778 test_134b() {
14779         remote_mds_nodsh && skip "remote MDS with nodsh"
14780         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14781                 skip "Need MDS version at least 2.7.54"
14782
14783         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14784         cancel_lru_locks mdc
14785
14786         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14787                         ldlm.lock_reclaim_threshold_mb)
14788         # disable reclaim temporarily
14789         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14790
14791         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14792         do_facet mds1 $LCTL set_param fail_loc=0x328
14793         do_facet mds1 $LCTL set_param fail_val=500
14794
14795         $LCTL set_param debug=+trace
14796
14797         local nr=600
14798         createmany -o $DIR/$tdir/f $nr &
14799         local create_pid=$!
14800
14801         echo "Sleep $TIMEOUT seconds ..."
14802         sleep $TIMEOUT
14803         if ! ps -p $create_pid  > /dev/null 2>&1; then
14804                 do_facet mds1 $LCTL set_param fail_loc=0
14805                 do_facet mds1 $LCTL set_param fail_val=0
14806                 do_facet mds1 $LCTL set_param \
14807                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14808                 error "createmany finished incorrectly!"
14809         fi
14810         do_facet mds1 $LCTL set_param fail_loc=0
14811         do_facet mds1 $LCTL set_param fail_val=0
14812         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14813         wait $create_pid || return 1
14814
14815         unlinkmany $DIR/$tdir/f $nr
14816 }
14817 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14818
14819 test_135() {
14820         remote_mds_nodsh && skip "remote MDS with nodsh"
14821         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14822                 skip "Need MDS version at least 2.13.50"
14823         local fname
14824
14825         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14826
14827 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14828         #set only one record at plain llog
14829         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14830
14831         #fill already existed plain llog each 64767
14832         #wrapping whole catalog
14833         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14834
14835         createmany -o $DIR/$tdir/$tfile_ 64700
14836         for (( i = 0; i < 64700; i = i + 2 ))
14837         do
14838                 rm $DIR/$tdir/$tfile_$i &
14839                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14840                 local pid=$!
14841                 wait $pid
14842         done
14843
14844         #waiting osp synchronization
14845         wait_delete_completed
14846 }
14847 run_test 135 "Race catalog processing"
14848
14849 test_136() {
14850         remote_mds_nodsh && skip "remote MDS with nodsh"
14851         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14852                 skip "Need MDS version at least 2.13.50"
14853         local fname
14854
14855         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14856         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14857         #set only one record at plain llog
14858 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14859         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14860
14861         #fill already existed 2 plain llogs each 64767
14862         #wrapping whole catalog
14863         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14864         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14865         wait_delete_completed
14866
14867         createmany -o $DIR/$tdir/$tfile_ 10
14868         sleep 25
14869
14870         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14871         for (( i = 0; i < 10; i = i + 3 ))
14872         do
14873                 rm $DIR/$tdir/$tfile_$i &
14874                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14875                 local pid=$!
14876                 wait $pid
14877                 sleep 7
14878                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14879         done
14880
14881         #waiting osp synchronization
14882         wait_delete_completed
14883 }
14884 run_test 136 "Race catalog processing 2"
14885
14886 test_140() { #bug-17379
14887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14888
14889         test_mkdir $DIR/$tdir
14890         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14891         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14892
14893         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14894         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14895         local i=0
14896         while i=$((i + 1)); do
14897                 test_mkdir $i
14898                 cd $i || error "Changing to $i"
14899                 ln -s ../stat stat || error "Creating stat symlink"
14900                 # Read the symlink until ELOOP present,
14901                 # not LBUGing the system is considered success,
14902                 # we didn't overrun the stack.
14903                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14904                 if [ $ret -ne 0 ]; then
14905                         if [ $ret -eq 40 ]; then
14906                                 break  # -ELOOP
14907                         else
14908                                 error "Open stat symlink"
14909                                         return
14910                         fi
14911                 fi
14912         done
14913         i=$((i - 1))
14914         echo "The symlink depth = $i"
14915         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14916                 error "Invalid symlink depth"
14917
14918         # Test recursive symlink
14919         ln -s symlink_self symlink_self
14920         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14921         echo "open symlink_self returns $ret"
14922         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14923 }
14924 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14925
14926 test_150a() {
14927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14928
14929         local TF="$TMP/$tfile"
14930
14931         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14932         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14933         cp $TF $DIR/$tfile
14934         cancel_lru_locks $OSC
14935         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14936         remount_client $MOUNT
14937         df -P $MOUNT
14938         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14939
14940         $TRUNCATE $TF 6000
14941         $TRUNCATE $DIR/$tfile 6000
14942         cancel_lru_locks $OSC
14943         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14944
14945         echo "12345" >>$TF
14946         echo "12345" >>$DIR/$tfile
14947         cancel_lru_locks $OSC
14948         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14949
14950         echo "12345" >>$TF
14951         echo "12345" >>$DIR/$tfile
14952         cancel_lru_locks $OSC
14953         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14954 }
14955 run_test 150a "truncate/append tests"
14956
14957 test_150b() {
14958         check_set_fallocate_or_skip
14959
14960         touch $DIR/$tfile
14961         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14962         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14963 }
14964 run_test 150b "Verify fallocate (prealloc) functionality"
14965
14966 test_150bb() {
14967         check_set_fallocate_or_skip
14968
14969         touch $DIR/$tfile
14970         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14971         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14972         > $DIR/$tfile
14973         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14974         # precomputed md5sum for 20MB of zeroes
14975         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14976         local sum=($(md5sum $DIR/$tfile))
14977
14978         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14979
14980         check_set_fallocate 1
14981
14982         > $DIR/$tfile
14983         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14984         sum=($(md5sum $DIR/$tfile))
14985
14986         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14987 }
14988 run_test 150bb "Verify fallocate modes both zero space"
14989
14990 test_150c() {
14991         check_set_fallocate_or_skip
14992         local striping="-c2"
14993
14994         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14995         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14996         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14997         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14998         local want=$((OSTCOUNT * 1048576))
14999
15000         # Must allocate all requested space, not more than 5% extra
15001         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15002                 error "bytes $bytes is not $want"
15003
15004         rm -f $DIR/$tfile
15005
15006         echo "verify fallocate on PFL file"
15007
15008         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15009
15010         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15011                 error "Create $DIR/$tfile failed"
15012         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15013         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15014         want=$((512 * 1048576))
15015
15016         # Must allocate all requested space, not more than 5% extra
15017         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15018                 error "bytes $bytes is not $want"
15019 }
15020 run_test 150c "Verify fallocate Size and Blocks"
15021
15022 test_150d() {
15023         check_set_fallocate_or_skip
15024         local striping="-c2"
15025
15026         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15027
15028         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15029         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15030                 error "setstripe failed"
15031         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15032         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15033         local want=$((OSTCOUNT * 1048576))
15034
15035         # Must allocate all requested space, not more than 5% extra
15036         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15037                 error "bytes $bytes is not $want"
15038 }
15039 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15040
15041 test_150e() {
15042         check_set_fallocate_or_skip
15043
15044         echo "df before:"
15045         $LFS df
15046         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15047         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15048                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15049
15050         # Find OST with Minimum Size
15051         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15052                        sort -un | head -1)
15053
15054         # Get 100MB per OST of the available space to reduce run time
15055         # else 60% of the available space if we are running SLOW tests
15056         if [ $SLOW == "no" ]; then
15057                 local space=$((1024 * 100 * OSTCOUNT))
15058         else
15059                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15060         fi
15061
15062         fallocate -l${space}k $DIR/$tfile ||
15063                 error "fallocate ${space}k $DIR/$tfile failed"
15064         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15065
15066         # get size immediately after fallocate. This should be correctly
15067         # updated
15068         local size=$(stat -c '%s' $DIR/$tfile)
15069         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15070
15071         # Sleep for a while for statfs to get updated. And not pull from cache.
15072         sleep 2
15073
15074         echo "df after fallocate:"
15075         $LFS df
15076
15077         (( size / 1024 == space )) || error "size $size != requested $space"
15078         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15079                 error "used $used < space $space"
15080
15081         rm $DIR/$tfile || error "rm failed"
15082         sync
15083         wait_delete_completed
15084
15085         echo "df after unlink:"
15086         $LFS df
15087 }
15088 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15089
15090 test_150f() {
15091         local size
15092         local blocks
15093         local want_size_before=20480 # in bytes
15094         local want_blocks_before=40 # 512 sized blocks
15095         local want_blocks_after=24  # 512 sized blocks
15096         local length=$(((want_blocks_before - want_blocks_after) * 512))
15097
15098         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15099                 skip "need at least 2.14.0 for fallocate punch"
15100
15101         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15102                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15103         fi
15104
15105         check_set_fallocate_or_skip
15106         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15107
15108         [[ "x$DOM" == "xyes" ]] &&
15109                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15110
15111         echo "Verify fallocate punch: Range within the file range"
15112         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15113                 error "dd failed for bs 4096 and count 5"
15114
15115         # Call fallocate with punch range which is within the file range
15116         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15117                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15118         # client must see changes immediately after fallocate
15119         size=$(stat -c '%s' $DIR/$tfile)
15120         blocks=$(stat -c '%b' $DIR/$tfile)
15121
15122         # Verify punch worked.
15123         (( blocks == want_blocks_after )) ||
15124                 error "punch failed: blocks $blocks != $want_blocks_after"
15125
15126         (( size == want_size_before )) ||
15127                 error "punch failed: size $size != $want_size_before"
15128
15129         # Verify there is hole in file
15130         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15131         # precomputed md5sum
15132         local expect="4a9a834a2db02452929c0a348273b4aa"
15133
15134         cksum=($(md5sum $DIR/$tfile))
15135         [[ "${cksum[0]}" == "$expect" ]] ||
15136                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15137
15138         # Start second sub-case for fallocate punch.
15139         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15140         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15141                 error "dd failed for bs 4096 and count 5"
15142
15143         # Punch range less than block size will have no change in block count
15144         want_blocks_after=40  # 512 sized blocks
15145
15146         # Punch overlaps two blocks and less than blocksize
15147         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15148                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15149         size=$(stat -c '%s' $DIR/$tfile)
15150         blocks=$(stat -c '%b' $DIR/$tfile)
15151
15152         # Verify punch worked.
15153         (( blocks == want_blocks_after )) ||
15154                 error "punch failed: blocks $blocks != $want_blocks_after"
15155
15156         (( size == want_size_before )) ||
15157                 error "punch failed: size $size != $want_size_before"
15158
15159         # Verify if range is really zero'ed out. We expect Zeros.
15160         # precomputed md5sum
15161         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15162         cksum=($(md5sum $DIR/$tfile))
15163         [[ "${cksum[0]}" == "$expect" ]] ||
15164                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15165 }
15166 run_test 150f "Verify fallocate punch functionality"
15167
15168 test_150g() {
15169         local space
15170         local size
15171         local blocks
15172         local blocks_after
15173         local size_after
15174         local BS=4096 # Block size in bytes
15175
15176         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15177                 skip "need at least 2.14.0 for fallocate punch"
15178
15179         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15180                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15181         fi
15182
15183         check_set_fallocate_or_skip
15184         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15185
15186         if [[ "x$DOM" == "xyes" ]]; then
15187                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15188                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15189         else
15190                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15191                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15192         fi
15193
15194         # Get 100MB per OST of the available space to reduce run time
15195         # else 60% of the available space if we are running SLOW tests
15196         if [ $SLOW == "no" ]; then
15197                 space=$((1024 * 100 * OSTCOUNT))
15198         else
15199                 # Find OST with Minimum Size
15200                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15201                         sort -un | head -1)
15202                 echo "min size OST: $space"
15203                 space=$(((space * 60)/100 * OSTCOUNT))
15204         fi
15205         # space in 1k units, round to 4k blocks
15206         local blkcount=$((space * 1024 / $BS))
15207
15208         echo "Verify fallocate punch: Very large Range"
15209         fallocate -l${space}k $DIR/$tfile ||
15210                 error "fallocate ${space}k $DIR/$tfile failed"
15211         # write 1M at the end, start and in the middle
15212         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15213                 error "dd failed: bs $BS count 256"
15214         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15215                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15216         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15217                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15218
15219         # Gather stats.
15220         size=$(stat -c '%s' $DIR/$tfile)
15221
15222         # gather punch length.
15223         local punch_size=$((size - (BS * 2)))
15224
15225         echo "punch_size = $punch_size"
15226         echo "size - punch_size: $((size - punch_size))"
15227         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15228
15229         # Call fallocate to punch all except 2 blocks. We leave the
15230         # first and the last block
15231         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15232         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15233                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15234
15235         size_after=$(stat -c '%s' $DIR/$tfile)
15236         blocks_after=$(stat -c '%b' $DIR/$tfile)
15237
15238         # Verify punch worked.
15239         # Size should be kept
15240         (( size == size_after )) ||
15241                 error "punch failed: size $size != $size_after"
15242
15243         # two 4k data blocks to remain plus possible 1 extra extent block
15244         (( blocks_after <= ((BS / 512) * 3) )) ||
15245                 error "too many blocks remains: $blocks_after"
15246
15247         # Verify that file has hole between the first and the last blocks
15248         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15249         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15250
15251         echo "Hole at [$hole_start, $hole_end)"
15252         (( hole_start == BS )) ||
15253                 error "no hole at offset $BS after punch"
15254
15255         (( hole_end == BS + punch_size )) ||
15256                 error "data at offset $hole_end < $((BS + punch_size))"
15257 }
15258 run_test 150g "Verify fallocate punch on large range"
15259
15260 #LU-2902 roc_hit was not able to read all values from lproc
15261 function roc_hit_init() {
15262         local list=$(comma_list $(osts_nodes))
15263         local dir=$DIR/$tdir-check
15264         local file=$dir/$tfile
15265         local BEFORE
15266         local AFTER
15267         local idx
15268
15269         test_mkdir $dir
15270         #use setstripe to do a write to every ost
15271         for i in $(seq 0 $((OSTCOUNT-1))); do
15272                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15273                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15274                 idx=$(printf %04x $i)
15275                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15276                         awk '$1 == "cache_access" {sum += $7}
15277                                 END { printf("%0.0f", sum) }')
15278
15279                 cancel_lru_locks osc
15280                 cat $file >/dev/null
15281
15282                 AFTER=$(get_osd_param $list *OST*$idx stats |
15283                         awk '$1 == "cache_access" {sum += $7}
15284                                 END { printf("%0.0f", sum) }')
15285
15286                 echo BEFORE:$BEFORE AFTER:$AFTER
15287                 if ! let "AFTER - BEFORE == 4"; then
15288                         rm -rf $dir
15289                         error "roc_hit is not safe to use"
15290                 fi
15291                 rm $file
15292         done
15293
15294         rm -rf $dir
15295 }
15296
15297 function roc_hit() {
15298         local list=$(comma_list $(osts_nodes))
15299         echo $(get_osd_param $list '' stats |
15300                 awk '$1 == "cache_hit" {sum += $7}
15301                         END { printf("%0.0f", sum) }')
15302 }
15303
15304 function set_cache() {
15305         local on=1
15306
15307         if [ "$2" == "off" ]; then
15308                 on=0;
15309         fi
15310         local list=$(comma_list $(osts_nodes))
15311         set_osd_param $list '' $1_cache_enable $on
15312
15313         cancel_lru_locks osc
15314 }
15315
15316 test_151() {
15317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15318         remote_ost_nodsh && skip "remote OST with nodsh"
15319
15320         local CPAGES=3
15321         local list=$(comma_list $(osts_nodes))
15322
15323         # check whether obdfilter is cache capable at all
15324         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15325                 skip "not cache-capable obdfilter"
15326         fi
15327
15328         # check cache is enabled on all obdfilters
15329         if get_osd_param $list '' read_cache_enable | grep 0; then
15330                 skip "oss cache is disabled"
15331         fi
15332
15333         set_osd_param $list '' writethrough_cache_enable 1
15334
15335         # check write cache is enabled on all obdfilters
15336         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15337                 skip "oss write cache is NOT enabled"
15338         fi
15339
15340         roc_hit_init
15341
15342         #define OBD_FAIL_OBD_NO_LRU  0x609
15343         do_nodes $list $LCTL set_param fail_loc=0x609
15344
15345         # pages should be in the case right after write
15346         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15347                 error "dd failed"
15348
15349         local BEFORE=$(roc_hit)
15350         cancel_lru_locks osc
15351         cat $DIR/$tfile >/dev/null
15352         local AFTER=$(roc_hit)
15353
15354         do_nodes $list $LCTL set_param fail_loc=0
15355
15356         if ! let "AFTER - BEFORE == CPAGES"; then
15357                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15358         fi
15359
15360         cancel_lru_locks osc
15361         # invalidates OST cache
15362         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15363         set_osd_param $list '' read_cache_enable 0
15364         cat $DIR/$tfile >/dev/null
15365
15366         # now data shouldn't be found in the cache
15367         BEFORE=$(roc_hit)
15368         cancel_lru_locks osc
15369         cat $DIR/$tfile >/dev/null
15370         AFTER=$(roc_hit)
15371         if let "AFTER - BEFORE != 0"; then
15372                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15373         fi
15374
15375         set_osd_param $list '' read_cache_enable 1
15376         rm -f $DIR/$tfile
15377 }
15378 run_test 151 "test cache on oss and controls ==============================="
15379
15380 test_152() {
15381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15382
15383         local TF="$TMP/$tfile"
15384
15385         # simulate ENOMEM during write
15386 #define OBD_FAIL_OST_NOMEM      0x226
15387         lctl set_param fail_loc=0x80000226
15388         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15389         cp $TF $DIR/$tfile
15390         sync || error "sync failed"
15391         lctl set_param fail_loc=0
15392
15393         # discard client's cache
15394         cancel_lru_locks osc
15395
15396         # simulate ENOMEM during read
15397         lctl set_param fail_loc=0x80000226
15398         cmp $TF $DIR/$tfile || error "cmp failed"
15399         lctl set_param fail_loc=0
15400
15401         rm -f $TF
15402 }
15403 run_test 152 "test read/write with enomem ============================"
15404
15405 test_153() {
15406         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15407 }
15408 run_test 153 "test if fdatasync does not crash ======================="
15409
15410 dot_lustre_fid_permission_check() {
15411         local fid=$1
15412         local ffid=$MOUNT/.lustre/fid/$fid
15413         local test_dir=$2
15414
15415         echo "stat fid $fid"
15416         stat $ffid || error "stat $ffid failed."
15417         echo "touch fid $fid"
15418         touch $ffid || error "touch $ffid failed."
15419         echo "write to fid $fid"
15420         cat /etc/hosts > $ffid || error "write $ffid failed."
15421         echo "read fid $fid"
15422         diff /etc/hosts $ffid || error "read $ffid failed."
15423         echo "append write to fid $fid"
15424         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15425         echo "rename fid $fid"
15426         mv $ffid $test_dir/$tfile.1 &&
15427                 error "rename $ffid to $tfile.1 should fail."
15428         touch $test_dir/$tfile.1
15429         mv $test_dir/$tfile.1 $ffid &&
15430                 error "rename $tfile.1 to $ffid should fail."
15431         rm -f $test_dir/$tfile.1
15432         echo "truncate fid $fid"
15433         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15434         echo "link fid $fid"
15435         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15436         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15437                 echo "setfacl fid $fid"
15438                 setfacl -R -m u:$USER0:rwx $ffid ||
15439                         error "setfacl $ffid failed"
15440                 echo "getfacl fid $fid"
15441                 getfacl $ffid || error "getfacl $ffid failed."
15442         fi
15443         echo "unlink fid $fid"
15444         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15445         echo "mknod fid $fid"
15446         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15447
15448         fid=[0xf00000400:0x1:0x0]
15449         ffid=$MOUNT/.lustre/fid/$fid
15450
15451         echo "stat non-exist fid $fid"
15452         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15453         echo "write to non-exist fid $fid"
15454         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15455         echo "link new fid $fid"
15456         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15457
15458         mkdir -p $test_dir/$tdir
15459         touch $test_dir/$tdir/$tfile
15460         fid=$($LFS path2fid $test_dir/$tdir)
15461         rc=$?
15462         [ $rc -ne 0 ] &&
15463                 error "error: could not get fid for $test_dir/$dir/$tfile."
15464
15465         ffid=$MOUNT/.lustre/fid/$fid
15466
15467         echo "ls $fid"
15468         ls $ffid || error "ls $ffid failed."
15469         echo "touch $fid/$tfile.1"
15470         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15471
15472         echo "touch $MOUNT/.lustre/fid/$tfile"
15473         touch $MOUNT/.lustre/fid/$tfile && \
15474                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15475
15476         echo "setxattr to $MOUNT/.lustre/fid"
15477         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15478
15479         echo "listxattr for $MOUNT/.lustre/fid"
15480         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15481
15482         echo "delxattr from $MOUNT/.lustre/fid"
15483         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15484
15485         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15486         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15487                 error "touch invalid fid should fail."
15488
15489         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15490         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15491                 error "touch non-normal fid should fail."
15492
15493         echo "rename $tdir to $MOUNT/.lustre/fid"
15494         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15495                 error "rename to $MOUNT/.lustre/fid should fail."
15496
15497         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15498         then            # LU-3547
15499                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15500                 local new_obf_mode=777
15501
15502                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15503                 chmod $new_obf_mode $DIR/.lustre/fid ||
15504                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15505
15506                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15507                 [ $obf_mode -eq $new_obf_mode ] ||
15508                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15509
15510                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15511                 chmod $old_obf_mode $DIR/.lustre/fid ||
15512                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15513         fi
15514
15515         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15516         fid=$($LFS path2fid $test_dir/$tfile-2)
15517
15518         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15519         then # LU-5424
15520                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15521                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15522                         error "create lov data thru .lustre failed"
15523         fi
15524         echo "cp /etc/passwd $test_dir/$tfile-2"
15525         cp /etc/passwd $test_dir/$tfile-2 ||
15526                 error "copy to $test_dir/$tfile-2 failed."
15527         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15528         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15529                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15530
15531         rm -rf $test_dir/tfile.lnk
15532         rm -rf $test_dir/$tfile-2
15533 }
15534
15535 test_154A() {
15536         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15537                 skip "Need MDS version at least 2.4.1"
15538
15539         local tf=$DIR/$tfile
15540         touch $tf
15541
15542         local fid=$($LFS path2fid $tf)
15543         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15544
15545         # check that we get the same pathname back
15546         local rootpath
15547         local found
15548         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15549                 echo "$rootpath $fid"
15550                 found=$($LFS fid2path $rootpath "$fid")
15551                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15552                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15553         done
15554
15555         # check wrong root path format
15556         rootpath=$MOUNT"_wrong"
15557         found=$($LFS fid2path $rootpath "$fid")
15558         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15559 }
15560 run_test 154A "lfs path2fid and fid2path basic checks"
15561
15562 test_154B() {
15563         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15564                 skip "Need MDS version at least 2.4.1"
15565
15566         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15567         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15568         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15569         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15570
15571         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15572         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15573
15574         # check that we get the same pathname
15575         echo "PFID: $PFID, name: $name"
15576         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15577         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15578         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15579                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15580
15581         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15582 }
15583 run_test 154B "verify the ll_decode_linkea tool"
15584
15585 test_154a() {
15586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15587         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15588         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15589                 skip "Need MDS version at least 2.2.51"
15590         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15591
15592         cp /etc/hosts $DIR/$tfile
15593
15594         fid=$($LFS path2fid $DIR/$tfile)
15595         rc=$?
15596         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15597
15598         dot_lustre_fid_permission_check "$fid" $DIR ||
15599                 error "dot lustre permission check $fid failed"
15600
15601         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15602
15603         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15604
15605         touch $MOUNT/.lustre/file &&
15606                 error "creation is not allowed under .lustre"
15607
15608         mkdir $MOUNT/.lustre/dir &&
15609                 error "mkdir is not allowed under .lustre"
15610
15611         rm -rf $DIR/$tfile
15612 }
15613 run_test 154a "Open-by-FID"
15614
15615 test_154b() {
15616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15617         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15619         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15620                 skip "Need MDS version at least 2.2.51"
15621
15622         local remote_dir=$DIR/$tdir/remote_dir
15623         local MDTIDX=1
15624         local rc=0
15625
15626         mkdir -p $DIR/$tdir
15627         $LFS mkdir -i $MDTIDX $remote_dir ||
15628                 error "create remote directory failed"
15629
15630         cp /etc/hosts $remote_dir/$tfile
15631
15632         fid=$($LFS path2fid $remote_dir/$tfile)
15633         rc=$?
15634         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15635
15636         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15637                 error "dot lustre permission check $fid failed"
15638         rm -rf $DIR/$tdir
15639 }
15640 run_test 154b "Open-by-FID for remote directory"
15641
15642 test_154c() {
15643         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15644                 skip "Need MDS version at least 2.4.1"
15645
15646         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15647         local FID1=$($LFS path2fid $DIR/$tfile.1)
15648         local FID2=$($LFS path2fid $DIR/$tfile.2)
15649         local FID3=$($LFS path2fid $DIR/$tfile.3)
15650
15651         local N=1
15652         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15653                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15654                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15655                 local want=FID$N
15656                 [ "$FID" = "${!want}" ] ||
15657                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15658                 N=$((N + 1))
15659         done
15660
15661         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15662         do
15663                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15664                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15665                 N=$((N + 1))
15666         done
15667 }
15668 run_test 154c "lfs path2fid and fid2path multiple arguments"
15669
15670 test_154d() {
15671         remote_mds_nodsh && skip "remote MDS with nodsh"
15672         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15673                 skip "Need MDS version at least 2.5.53"
15674
15675         if remote_mds; then
15676                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15677         else
15678                 nid="0@lo"
15679         fi
15680         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15681         local fd
15682         local cmd
15683
15684         rm -f $DIR/$tfile
15685         touch $DIR/$tfile
15686
15687         local fid=$($LFS path2fid $DIR/$tfile)
15688         # Open the file
15689         fd=$(free_fd)
15690         cmd="exec $fd<$DIR/$tfile"
15691         eval $cmd
15692         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15693         echo "$fid_list" | grep "$fid"
15694         rc=$?
15695
15696         cmd="exec $fd>/dev/null"
15697         eval $cmd
15698         if [ $rc -ne 0 ]; then
15699                 error "FID $fid not found in open files list $fid_list"
15700         fi
15701 }
15702 run_test 154d "Verify open file fid"
15703
15704 test_154e()
15705 {
15706         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15707                 skip "Need MDS version at least 2.6.50"
15708
15709         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15710                 error ".lustre returned by readdir"
15711         fi
15712 }
15713 run_test 154e ".lustre is not returned by readdir"
15714
15715 test_154f() {
15716         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15717
15718         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15719         mkdir_on_mdt0 $DIR/$tdir
15720         # test dirs inherit from its stripe
15721         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15722         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15723         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15724         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15725         touch $DIR/f
15726
15727         # get fid of parents
15728         local FID0=$($LFS path2fid $DIR/$tdir)
15729         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15730         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15731         local FID3=$($LFS path2fid $DIR)
15732
15733         # check that path2fid --parents returns expected <parent_fid>/name
15734         # 1) test for a directory (single parent)
15735         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15736         [ "$parent" == "$FID0/foo1" ] ||
15737                 error "expected parent: $FID0/foo1, got: $parent"
15738
15739         # 2) test for a file with nlink > 1 (multiple parents)
15740         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15741         echo "$parent" | grep -F "$FID1/$tfile" ||
15742                 error "$FID1/$tfile not returned in parent list"
15743         echo "$parent" | grep -F "$FID2/link" ||
15744                 error "$FID2/link not returned in parent list"
15745
15746         # 3) get parent by fid
15747         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15748         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15749         echo "$parent" | grep -F "$FID1/$tfile" ||
15750                 error "$FID1/$tfile not returned in parent list (by fid)"
15751         echo "$parent" | grep -F "$FID2/link" ||
15752                 error "$FID2/link not returned in parent list (by fid)"
15753
15754         # 4) test for entry in root directory
15755         parent=$($LFS path2fid --parents $DIR/f)
15756         echo "$parent" | grep -F "$FID3/f" ||
15757                 error "$FID3/f not returned in parent list"
15758
15759         # 5) test it on root directory
15760         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15761                 error "$MOUNT should not have parents"
15762
15763         # enable xattr caching and check that linkea is correctly updated
15764         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15765         save_lustre_params client "llite.*.xattr_cache" > $save
15766         lctl set_param llite.*.xattr_cache 1
15767
15768         # 6.1) linkea update on rename
15769         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15770
15771         # get parents by fid
15772         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15773         # foo1 should no longer be returned in parent list
15774         echo "$parent" | grep -F "$FID1" &&
15775                 error "$FID1 should no longer be in parent list"
15776         # the new path should appear
15777         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15778                 error "$FID2/$tfile.moved is not in parent list"
15779
15780         # 6.2) linkea update on unlink
15781         rm -f $DIR/$tdir/foo2/link
15782         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15783         # foo2/link should no longer be returned in parent list
15784         echo "$parent" | grep -F "$FID2/link" &&
15785                 error "$FID2/link should no longer be in parent list"
15786         true
15787
15788         rm -f $DIR/f
15789         restore_lustre_params < $save
15790         rm -f $save
15791 }
15792 run_test 154f "get parent fids by reading link ea"
15793
15794 test_154g()
15795 {
15796         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15797         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15798            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15799                 skip "Need MDS version at least 2.6.92"
15800
15801         mkdir_on_mdt0 $DIR/$tdir
15802         llapi_fid_test -d $DIR/$tdir
15803 }
15804 run_test 154g "various llapi FID tests"
15805
15806 test_155_small_load() {
15807     local temp=$TMP/$tfile
15808     local file=$DIR/$tfile
15809
15810     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15811         error "dd of=$temp bs=6096 count=1 failed"
15812     cp $temp $file
15813     cancel_lru_locks $OSC
15814     cmp $temp $file || error "$temp $file differ"
15815
15816     $TRUNCATE $temp 6000
15817     $TRUNCATE $file 6000
15818     cmp $temp $file || error "$temp $file differ (truncate1)"
15819
15820     echo "12345" >>$temp
15821     echo "12345" >>$file
15822     cmp $temp $file || error "$temp $file differ (append1)"
15823
15824     echo "12345" >>$temp
15825     echo "12345" >>$file
15826     cmp $temp $file || error "$temp $file differ (append2)"
15827
15828     rm -f $temp $file
15829     true
15830 }
15831
15832 test_155_big_load() {
15833         remote_ost_nodsh && skip "remote OST with nodsh"
15834
15835         local temp=$TMP/$tfile
15836         local file=$DIR/$tfile
15837
15838         free_min_max
15839         local cache_size=$(do_facet ost$((MAXI+1)) \
15840                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15841
15842         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15843         # pre-set value
15844         if [ -z "$cache_size" ]; then
15845                 cache_size=256
15846         fi
15847         local large_file_size=$((cache_size * 2))
15848
15849         echo "OSS cache size: $cache_size KB"
15850         echo "Large file size: $large_file_size KB"
15851
15852         [ $MAXV -le $large_file_size ] &&
15853                 skip_env "max available OST size needs > $large_file_size KB"
15854
15855         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15856
15857         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15858                 error "dd of=$temp bs=$large_file_size count=1k failed"
15859         cp $temp $file
15860         ls -lh $temp $file
15861         cancel_lru_locks osc
15862         cmp $temp $file || error "$temp $file differ"
15863
15864         rm -f $temp $file
15865         true
15866 }
15867
15868 save_writethrough() {
15869         local facets=$(get_facets OST)
15870
15871         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15872 }
15873
15874 test_155a() {
15875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15876
15877         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15878
15879         save_writethrough $p
15880
15881         set_cache read on
15882         set_cache writethrough on
15883         test_155_small_load
15884         restore_lustre_params < $p
15885         rm -f $p
15886 }
15887 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15888
15889 test_155b() {
15890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15891
15892         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15893
15894         save_writethrough $p
15895
15896         set_cache read on
15897         set_cache writethrough off
15898         test_155_small_load
15899         restore_lustre_params < $p
15900         rm -f $p
15901 }
15902 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15903
15904 test_155c() {
15905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15906
15907         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15908
15909         save_writethrough $p
15910
15911         set_cache read off
15912         set_cache writethrough on
15913         test_155_small_load
15914         restore_lustre_params < $p
15915         rm -f $p
15916 }
15917 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15918
15919 test_155d() {
15920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15921
15922         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15923
15924         save_writethrough $p
15925
15926         set_cache read off
15927         set_cache writethrough off
15928         test_155_small_load
15929         restore_lustre_params < $p
15930         rm -f $p
15931 }
15932 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15933
15934 test_155e() {
15935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15936
15937         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15938
15939         save_writethrough $p
15940
15941         set_cache read on
15942         set_cache writethrough on
15943         test_155_big_load
15944         restore_lustre_params < $p
15945         rm -f $p
15946 }
15947 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15948
15949 test_155f() {
15950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15951
15952         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15953
15954         save_writethrough $p
15955
15956         set_cache read on
15957         set_cache writethrough off
15958         test_155_big_load
15959         restore_lustre_params < $p
15960         rm -f $p
15961 }
15962 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15963
15964 test_155g() {
15965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15966
15967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15968
15969         save_writethrough $p
15970
15971         set_cache read off
15972         set_cache writethrough on
15973         test_155_big_load
15974         restore_lustre_params < $p
15975         rm -f $p
15976 }
15977 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15978
15979 test_155h() {
15980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15981
15982         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15983
15984         save_writethrough $p
15985
15986         set_cache read off
15987         set_cache writethrough off
15988         test_155_big_load
15989         restore_lustre_params < $p
15990         rm -f $p
15991 }
15992 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15993
15994 test_156() {
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996         remote_ost_nodsh && skip "remote OST with nodsh"
15997         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15998                 skip "stats not implemented on old servers"
15999         [ "$ost1_FSTYPE" = "zfs" ] &&
16000                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16001
16002         local CPAGES=3
16003         local BEFORE
16004         local AFTER
16005         local file="$DIR/$tfile"
16006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16007
16008         save_writethrough $p
16009         roc_hit_init
16010
16011         log "Turn on read and write cache"
16012         set_cache read on
16013         set_cache writethrough on
16014
16015         log "Write data and read it back."
16016         log "Read should be satisfied from the cache."
16017         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16018         BEFORE=$(roc_hit)
16019         cancel_lru_locks osc
16020         cat $file >/dev/null
16021         AFTER=$(roc_hit)
16022         if ! let "AFTER - BEFORE == CPAGES"; then
16023                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16024         else
16025                 log "cache hits: before: $BEFORE, after: $AFTER"
16026         fi
16027
16028         log "Read again; it should be satisfied from the cache."
16029         BEFORE=$AFTER
16030         cancel_lru_locks osc
16031         cat $file >/dev/null
16032         AFTER=$(roc_hit)
16033         if ! let "AFTER - BEFORE == CPAGES"; then
16034                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16035         else
16036                 log "cache hits:: before: $BEFORE, after: $AFTER"
16037         fi
16038
16039         log "Turn off the read cache and turn on the write cache"
16040         set_cache read off
16041         set_cache writethrough on
16042
16043         log "Read again; it should be satisfied from the cache."
16044         BEFORE=$(roc_hit)
16045         cancel_lru_locks osc
16046         cat $file >/dev/null
16047         AFTER=$(roc_hit)
16048         if ! let "AFTER - BEFORE == CPAGES"; then
16049                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16050         else
16051                 log "cache hits:: before: $BEFORE, after: $AFTER"
16052         fi
16053
16054         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16055                 # > 2.12.56 uses pagecache if cached
16056                 log "Read again; it should not be satisfied from the cache."
16057                 BEFORE=$AFTER
16058                 cancel_lru_locks osc
16059                 cat $file >/dev/null
16060                 AFTER=$(roc_hit)
16061                 if ! let "AFTER - BEFORE == 0"; then
16062                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16063                 else
16064                         log "cache hits:: before: $BEFORE, after: $AFTER"
16065                 fi
16066         fi
16067
16068         log "Write data and read it back."
16069         log "Read should be satisfied from the cache."
16070         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16071         BEFORE=$(roc_hit)
16072         cancel_lru_locks osc
16073         cat $file >/dev/null
16074         AFTER=$(roc_hit)
16075         if ! let "AFTER - BEFORE == CPAGES"; then
16076                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16077         else
16078                 log "cache hits:: before: $BEFORE, after: $AFTER"
16079         fi
16080
16081         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16082                 # > 2.12.56 uses pagecache if cached
16083                 log "Read again; it should not be satisfied from the cache."
16084                 BEFORE=$AFTER
16085                 cancel_lru_locks osc
16086                 cat $file >/dev/null
16087                 AFTER=$(roc_hit)
16088                 if ! let "AFTER - BEFORE == 0"; then
16089                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16090                 else
16091                         log "cache hits:: before: $BEFORE, after: $AFTER"
16092                 fi
16093         fi
16094
16095         log "Turn off read and write cache"
16096         set_cache read off
16097         set_cache writethrough off
16098
16099         log "Write data and read it back"
16100         log "It should not be satisfied from the cache."
16101         rm -f $file
16102         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16103         cancel_lru_locks osc
16104         BEFORE=$(roc_hit)
16105         cat $file >/dev/null
16106         AFTER=$(roc_hit)
16107         if ! let "AFTER - BEFORE == 0"; then
16108                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16109         else
16110                 log "cache hits:: before: $BEFORE, after: $AFTER"
16111         fi
16112
16113         log "Turn on the read cache and turn off the write cache"
16114         set_cache read on
16115         set_cache writethrough off
16116
16117         log "Write data and read it back"
16118         log "It should not be satisfied from the cache."
16119         rm -f $file
16120         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16121         BEFORE=$(roc_hit)
16122         cancel_lru_locks osc
16123         cat $file >/dev/null
16124         AFTER=$(roc_hit)
16125         if ! let "AFTER - BEFORE == 0"; then
16126                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16127         else
16128                 log "cache hits:: before: $BEFORE, after: $AFTER"
16129         fi
16130
16131         log "Read again; it should be satisfied from the cache."
16132         BEFORE=$(roc_hit)
16133         cancel_lru_locks osc
16134         cat $file >/dev/null
16135         AFTER=$(roc_hit)
16136         if ! let "AFTER - BEFORE == CPAGES"; then
16137                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16138         else
16139                 log "cache hits:: before: $BEFORE, after: $AFTER"
16140         fi
16141
16142         restore_lustre_params < $p
16143         rm -f $p $file
16144 }
16145 run_test 156 "Verification of tunables"
16146
16147 test_160a() {
16148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16149         remote_mds_nodsh && skip "remote MDS with nodsh"
16150         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16151                 skip "Need MDS version at least 2.2.0"
16152
16153         changelog_register || error "changelog_register failed"
16154         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16155         changelog_users $SINGLEMDS | grep -q $cl_user ||
16156                 error "User $cl_user not found in changelog_users"
16157
16158         mkdir_on_mdt0 $DIR/$tdir
16159
16160         # change something
16161         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16162         changelog_clear 0 || error "changelog_clear failed"
16163         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16164         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16165         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16166         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16167         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16168         rm $DIR/$tdir/pics/desktop.jpg
16169
16170         echo "verifying changelog mask"
16171         changelog_chmask "-MKDIR"
16172         changelog_chmask "-CLOSE"
16173
16174         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16175         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16176
16177         changelog_chmask "+MKDIR"
16178         changelog_chmask "+CLOSE"
16179
16180         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16181         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16182
16183         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16184         CLOSES=$(changelog_dump | grep -c "CLOSE")
16185         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16186         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16187
16188         # verify contents
16189         echo "verifying target fid"
16190         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16191         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16192         [ "$fidc" == "$fidf" ] ||
16193                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16194         echo "verifying parent fid"
16195         # The FID returned from the Changelog may be the directory shard on
16196         # a different MDT, and not the FID returned by path2fid on the parent.
16197         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16198         # since this is what will matter when recreating this file in the tree.
16199         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16200         local pathp=$($LFS fid2path $MOUNT "$fidp")
16201         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16202                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16203
16204         echo "getting records for $cl_user"
16205         changelog_users $SINGLEMDS
16206         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16207         local nclr=3
16208         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16209                 error "changelog_clear failed"
16210         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16211         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16212         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16213                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16214
16215         local min0_rec=$(changelog_users $SINGLEMDS |
16216                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16217         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16218                           awk '{ print $1; exit; }')
16219
16220         changelog_dump | tail -n 5
16221         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16222         [ $first_rec == $((min0_rec + 1)) ] ||
16223                 error "first index should be $min0_rec + 1 not $first_rec"
16224
16225         # LU-3446 changelog index reset on MDT restart
16226         local cur_rec1=$(changelog_users $SINGLEMDS |
16227                          awk '/^current.index:/ { print $NF }')
16228         changelog_clear 0 ||
16229                 error "clear all changelog records for $cl_user failed"
16230         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16231         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16232                 error "Fail to start $SINGLEMDS"
16233         local cur_rec2=$(changelog_users $SINGLEMDS |
16234                          awk '/^current.index:/ { print $NF }')
16235         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16236         [ $cur_rec1 == $cur_rec2 ] ||
16237                 error "current index should be $cur_rec1 not $cur_rec2"
16238
16239         echo "verifying users from this test are deregistered"
16240         changelog_deregister || error "changelog_deregister failed"
16241         changelog_users $SINGLEMDS | grep -q $cl_user &&
16242                 error "User '$cl_user' still in changelog_users"
16243
16244         # lctl get_param -n mdd.*.changelog_users
16245         # current_index: 144
16246         # ID    index (idle seconds)
16247         # cl3   144   (2) mask=<list>
16248         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16249                 # this is the normal case where all users were deregistered
16250                 # make sure no new records are added when no users are present
16251                 local last_rec1=$(changelog_users $SINGLEMDS |
16252                                   awk '/^current.index:/ { print $NF }')
16253                 touch $DIR/$tdir/chloe
16254                 local last_rec2=$(changelog_users $SINGLEMDS |
16255                                   awk '/^current.index:/ { print $NF }')
16256                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16257                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16258         else
16259                 # any changelog users must be leftovers from a previous test
16260                 changelog_users $SINGLEMDS
16261                 echo "other changelog users; can't verify off"
16262         fi
16263 }
16264 run_test 160a "changelog sanity"
16265
16266 test_160b() { # LU-3587
16267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16268         remote_mds_nodsh && skip "remote MDS with nodsh"
16269         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16270                 skip "Need MDS version at least 2.2.0"
16271
16272         changelog_register || error "changelog_register failed"
16273         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16274         changelog_users $SINGLEMDS | grep -q $cl_user ||
16275                 error "User '$cl_user' not found in changelog_users"
16276
16277         local longname1=$(str_repeat a 255)
16278         local longname2=$(str_repeat b 255)
16279
16280         cd $DIR
16281         echo "creating very long named file"
16282         touch $longname1 || error "create of '$longname1' failed"
16283         echo "renaming very long named file"
16284         mv $longname1 $longname2
16285
16286         changelog_dump | grep RENME | tail -n 5
16287         rm -f $longname2
16288 }
16289 run_test 160b "Verify that very long rename doesn't crash in changelog"
16290
16291 test_160c() {
16292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16293         remote_mds_nodsh && skip "remote MDS with nodsh"
16294
16295         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16296                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16297                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16298                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16299
16300         local rc=0
16301
16302         # Registration step
16303         changelog_register || error "changelog_register failed"
16304
16305         rm -rf $DIR/$tdir
16306         mkdir -p $DIR/$tdir
16307         $MCREATE $DIR/$tdir/foo_160c
16308         changelog_chmask "-TRUNC"
16309         $TRUNCATE $DIR/$tdir/foo_160c 200
16310         changelog_chmask "+TRUNC"
16311         $TRUNCATE $DIR/$tdir/foo_160c 199
16312         changelog_dump | tail -n 5
16313         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16314         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16315 }
16316 run_test 160c "verify that changelog log catch the truncate event"
16317
16318 test_160d() {
16319         remote_mds_nodsh && skip "remote MDS with nodsh"
16320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16322         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16323                 skip "Need MDS version at least 2.7.60"
16324
16325         # Registration step
16326         changelog_register || error "changelog_register failed"
16327
16328         mkdir -p $DIR/$tdir/migrate_dir
16329         changelog_clear 0 || error "changelog_clear failed"
16330
16331         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16332         changelog_dump | tail -n 5
16333         local migrates=$(changelog_dump | grep -c "MIGRT")
16334         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16335 }
16336 run_test 160d "verify that changelog log catch the migrate event"
16337
16338 test_160e() {
16339         remote_mds_nodsh && skip "remote MDS with nodsh"
16340
16341         # Create a user
16342         changelog_register || error "changelog_register failed"
16343
16344         local MDT0=$(facet_svc $SINGLEMDS)
16345         local rc
16346
16347         # No user (expect fail)
16348         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16349         rc=$?
16350         if [ $rc -eq 0 ]; then
16351                 error "Should fail without user"
16352         elif [ $rc -ne 4 ]; then
16353                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16354         fi
16355
16356         # Delete a future user (expect fail)
16357         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16358         rc=$?
16359         if [ $rc -eq 0 ]; then
16360                 error "Deleted non-existant user cl77"
16361         elif [ $rc -ne 2 ]; then
16362                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16363         fi
16364
16365         # Clear to a bad index (1 billion should be safe)
16366         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16367         rc=$?
16368
16369         if [ $rc -eq 0 ]; then
16370                 error "Successfully cleared to invalid CL index"
16371         elif [ $rc -ne 22 ]; then
16372                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16373         fi
16374 }
16375 run_test 160e "changelog negative testing (should return errors)"
16376
16377 test_160f() {
16378         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16379         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16380                 skip "Need MDS version at least 2.10.56"
16381
16382         local mdts=$(comma_list $(mdts_nodes))
16383
16384         # Create a user
16385         changelog_register || error "first changelog_register failed"
16386         changelog_register || error "second changelog_register failed"
16387         local cl_users
16388         declare -A cl_user1
16389         declare -A cl_user2
16390         local user_rec1
16391         local user_rec2
16392         local i
16393
16394         # generate some changelog records to accumulate on each MDT
16395         # use all_char because created files should be evenly distributed
16396         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16397                 error "test_mkdir $tdir failed"
16398         log "$(date +%s): creating first files"
16399         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16400                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16401                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16402         done
16403
16404         # check changelogs have been generated
16405         local start=$SECONDS
16406         local idle_time=$((MDSCOUNT * 5 + 5))
16407         local nbcl=$(changelog_dump | wc -l)
16408         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16409
16410         for param in "changelog_max_idle_time=$idle_time" \
16411                      "changelog_gc=1" \
16412                      "changelog_min_gc_interval=2" \
16413                      "changelog_min_free_cat_entries=3"; do
16414                 local MDT0=$(facet_svc $SINGLEMDS)
16415                 local var="${param%=*}"
16416                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16417
16418                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16419                 do_nodes $mdts $LCTL set_param mdd.*.$param
16420         done
16421
16422         # force cl_user2 to be idle (1st part), but also cancel the
16423         # cl_user1 records so that it is not evicted later in the test.
16424         local sleep1=$((idle_time / 2))
16425         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16426         sleep $sleep1
16427
16428         # simulate changelog catalog almost full
16429         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16430         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16431
16432         for i in $(seq $MDSCOUNT); do
16433                 cl_users=(${CL_USERS[mds$i]})
16434                 cl_user1[mds$i]="${cl_users[0]}"
16435                 cl_user2[mds$i]="${cl_users[1]}"
16436
16437                 [ -n "${cl_user1[mds$i]}" ] ||
16438                         error "mds$i: no user registered"
16439                 [ -n "${cl_user2[mds$i]}" ] ||
16440                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16441
16442                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16443                 [ -n "$user_rec1" ] ||
16444                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16445                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16446                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16447                 [ -n "$user_rec2" ] ||
16448                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16449                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16450                      "$user_rec1 + 2 == $user_rec2"
16451                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16452                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16453                               "$user_rec1 + 2, but is $user_rec2"
16454                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16455                 [ -n "$user_rec2" ] ||
16456                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16457                 [ $user_rec1 == $user_rec2 ] ||
16458                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16459                               "$user_rec1, but is $user_rec2"
16460         done
16461
16462         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16463         local sleep2=$((idle_time - (SECONDS - start) + 1))
16464         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16465         sleep $sleep2
16466
16467         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16468         # cl_user1 should be OK because it recently processed records.
16469         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16470         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16471                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16472                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16473         done
16474
16475         # ensure gc thread is done
16476         for i in $(mdts_nodes); do
16477                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16478                         error "$i: GC-thread not done"
16479         done
16480
16481         local first_rec
16482         for (( i = 1; i <= MDSCOUNT; i++ )); do
16483                 # check cl_user1 still registered
16484                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16485                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16486                 # check cl_user2 unregistered
16487                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16488                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16489
16490                 # check changelogs are present and starting at $user_rec1 + 1
16491                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16492                 [ -n "$user_rec1" ] ||
16493                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16494                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16495                             awk '{ print $1; exit; }')
16496
16497                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16498                 [ $((user_rec1 + 1)) == $first_rec ] ||
16499                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16500         done
16501 }
16502 run_test 160f "changelog garbage collect (timestamped users)"
16503
16504 test_160g() {
16505         remote_mds_nodsh && skip "remote MDS with nodsh"
16506         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16507                 skip "Need MDS version at least 2.14.55"
16508
16509         local mdts=$(comma_list $(mdts_nodes))
16510
16511         # Create a user
16512         changelog_register || error "first changelog_register failed"
16513         changelog_register || error "second changelog_register failed"
16514         local cl_users
16515         declare -A cl_user1
16516         declare -A cl_user2
16517         local user_rec1
16518         local user_rec2
16519         local i
16520
16521         # generate some changelog records to accumulate on each MDT
16522         # use all_char because created files should be evenly distributed
16523         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16524                 error "test_mkdir $tdir failed"
16525         for ((i = 0; i < MDSCOUNT; i++)); do
16526                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16527                         error "create $DIR/$tdir/d$i.1 failed"
16528         done
16529
16530         # check changelogs have been generated
16531         local nbcl=$(changelog_dump | wc -l)
16532         (( $nbcl > 0 )) || error "no changelogs found"
16533
16534         # reduce the max_idle_indexes value to make sure we exceed it
16535         for param in "changelog_max_idle_indexes=2" \
16536                      "changelog_gc=1" \
16537                      "changelog_min_gc_interval=2"; do
16538                 local MDT0=$(facet_svc $SINGLEMDS)
16539                 local var="${param%=*}"
16540                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16541
16542                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16543                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16544                         error "unable to set mdd.*.$param"
16545         done
16546
16547         local start=$SECONDS
16548         for i in $(seq $MDSCOUNT); do
16549                 cl_users=(${CL_USERS[mds$i]})
16550                 cl_user1[mds$i]="${cl_users[0]}"
16551                 cl_user2[mds$i]="${cl_users[1]}"
16552
16553                 [ -n "${cl_user1[mds$i]}" ] ||
16554                         error "mds$i: user1 is not registered"
16555                 [ -n "${cl_user2[mds$i]}" ] ||
16556                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16557
16558                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16559                 [ -n "$user_rec1" ] ||
16560                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16561                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16562                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16563                 [ -n "$user_rec2" ] ||
16564                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16565                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16566                      "$user_rec1 + 2 == $user_rec2"
16567                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16568                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16569                               "expected $user_rec1 + 2, but is $user_rec2"
16570                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16571                 [ -n "$user_rec2" ] ||
16572                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16573                 [ $user_rec1 == $user_rec2 ] ||
16574                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16575                               "expected $user_rec1, but is $user_rec2"
16576         done
16577
16578         # ensure we are past the previous changelog_min_gc_interval set above
16579         local sleep2=$((start + 2 - SECONDS))
16580         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16581         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16582         # cl_user1 should be OK because it recently processed records.
16583         for ((i = 0; i < MDSCOUNT; i++)); do
16584                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16585                         error "create $DIR/$tdir/d$i.3 failed"
16586         done
16587
16588         # ensure gc thread is done
16589         for i in $(mdts_nodes); do
16590                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16591                         error "$i: GC-thread not done"
16592         done
16593
16594         local first_rec
16595         for (( i = 1; i <= MDSCOUNT; i++ )); do
16596                 # check cl_user1 still registered
16597                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16598                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16599                 # check cl_user2 unregistered
16600                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16601                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16602
16603                 # check changelogs are present and starting at $user_rec1 + 1
16604                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16605                 [ -n "$user_rec1" ] ||
16606                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16607                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16608                             awk '{ print $1; exit; }')
16609
16610                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16611                 [ $((user_rec1 + 1)) == $first_rec ] ||
16612                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16613         done
16614 }
16615 run_test 160g "changelog garbage collect on idle records"
16616
16617 test_160h() {
16618         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16619         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16620                 skip "Need MDS version at least 2.10.56"
16621
16622         local mdts=$(comma_list $(mdts_nodes))
16623
16624         # Create a user
16625         changelog_register || error "first changelog_register failed"
16626         changelog_register || error "second changelog_register failed"
16627         local cl_users
16628         declare -A cl_user1
16629         declare -A cl_user2
16630         local user_rec1
16631         local user_rec2
16632         local i
16633
16634         # generate some changelog records to accumulate on each MDT
16635         # use all_char because created files should be evenly distributed
16636         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16637                 error "test_mkdir $tdir failed"
16638         for ((i = 0; i < MDSCOUNT; i++)); do
16639                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16640                         error "create $DIR/$tdir/d$i.1 failed"
16641         done
16642
16643         # check changelogs have been generated
16644         local nbcl=$(changelog_dump | wc -l)
16645         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16646
16647         for param in "changelog_max_idle_time=10" \
16648                      "changelog_gc=1" \
16649                      "changelog_min_gc_interval=2"; do
16650                 local MDT0=$(facet_svc $SINGLEMDS)
16651                 local var="${param%=*}"
16652                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16653
16654                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16655                 do_nodes $mdts $LCTL set_param mdd.*.$param
16656         done
16657
16658         # force cl_user2 to be idle (1st part)
16659         sleep 9
16660
16661         for i in $(seq $MDSCOUNT); do
16662                 cl_users=(${CL_USERS[mds$i]})
16663                 cl_user1[mds$i]="${cl_users[0]}"
16664                 cl_user2[mds$i]="${cl_users[1]}"
16665
16666                 [ -n "${cl_user1[mds$i]}" ] ||
16667                         error "mds$i: no user registered"
16668                 [ -n "${cl_user2[mds$i]}" ] ||
16669                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16670
16671                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16672                 [ -n "$user_rec1" ] ||
16673                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16674                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16675                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16676                 [ -n "$user_rec2" ] ||
16677                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16678                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16679                      "$user_rec1 + 2 == $user_rec2"
16680                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16681                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16682                               "$user_rec1 + 2, but is $user_rec2"
16683                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16684                 [ -n "$user_rec2" ] ||
16685                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16686                 [ $user_rec1 == $user_rec2 ] ||
16687                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16688                               "$user_rec1, but is $user_rec2"
16689         done
16690
16691         # force cl_user2 to be idle (2nd part) and to reach
16692         # changelog_max_idle_time
16693         sleep 2
16694
16695         # force each GC-thread start and block then
16696         # one per MDT/MDD, set fail_val accordingly
16697         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16698         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16699
16700         # generate more changelogs to trigger fail_loc
16701         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16702                 error "create $DIR/$tdir/${tfile}bis failed"
16703
16704         # stop MDT to stop GC-thread, should be done in back-ground as it will
16705         # block waiting for the thread to be released and exit
16706         declare -A stop_pids
16707         for i in $(seq $MDSCOUNT); do
16708                 stop mds$i &
16709                 stop_pids[mds$i]=$!
16710         done
16711
16712         for i in $(mdts_nodes); do
16713                 local facet
16714                 local nb=0
16715                 local facets=$(facets_up_on_host $i)
16716
16717                 for facet in ${facets//,/ }; do
16718                         if [[ $facet == mds* ]]; then
16719                                 nb=$((nb + 1))
16720                         fi
16721                 done
16722                 # ensure each MDS's gc threads are still present and all in "R"
16723                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16724                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16725                         error "$i: expected $nb GC-thread"
16726                 wait_update $i \
16727                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16728                         "R" 20 ||
16729                         error "$i: GC-thread not found in R-state"
16730                 # check umounts of each MDT on MDS have reached kthread_stop()
16731                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16732                         error "$i: expected $nb umount"
16733                 wait_update $i \
16734                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16735                         error "$i: umount not found in D-state"
16736         done
16737
16738         # release all GC-threads
16739         do_nodes $mdts $LCTL set_param fail_loc=0
16740
16741         # wait for MDT stop to complete
16742         for i in $(seq $MDSCOUNT); do
16743                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16744         done
16745
16746         # XXX
16747         # may try to check if any orphan changelog records are present
16748         # via ldiskfs/zfs and llog_reader...
16749
16750         # re-start/mount MDTs
16751         for i in $(seq $MDSCOUNT); do
16752                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16753                         error "Fail to start mds$i"
16754         done
16755
16756         local first_rec
16757         for i in $(seq $MDSCOUNT); do
16758                 # check cl_user1 still registered
16759                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16760                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16761                 # check cl_user2 unregistered
16762                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16763                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16764
16765                 # check changelogs are present and starting at $user_rec1 + 1
16766                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16767                 [ -n "$user_rec1" ] ||
16768                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16769                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16770                             awk '{ print $1; exit; }')
16771
16772                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16773                 [ $((user_rec1 + 1)) == $first_rec ] ||
16774                         error "mds$i: first index should be $user_rec1 + 1, " \
16775                               "but is $first_rec"
16776         done
16777 }
16778 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16779               "during mount"
16780
16781 test_160i() {
16782
16783         local mdts=$(comma_list $(mdts_nodes))
16784
16785         changelog_register || error "first changelog_register failed"
16786
16787         # generate some changelog records to accumulate on each MDT
16788         # use all_char because created files should be evenly distributed
16789         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16790                 error "test_mkdir $tdir failed"
16791         for ((i = 0; i < MDSCOUNT; i++)); do
16792                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16793                         error "create $DIR/$tdir/d$i.1 failed"
16794         done
16795
16796         # check changelogs have been generated
16797         local nbcl=$(changelog_dump | wc -l)
16798         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16799
16800         # simulate race between register and unregister
16801         # XXX as fail_loc is set per-MDS, with DNE configs the race
16802         # simulation will only occur for one MDT per MDS and for the
16803         # others the normal race scenario will take place
16804         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16805         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16806         do_nodes $mdts $LCTL set_param fail_val=1
16807
16808         # unregister 1st user
16809         changelog_deregister &
16810         local pid1=$!
16811         # wait some time for deregister work to reach race rdv
16812         sleep 2
16813         # register 2nd user
16814         changelog_register || error "2nd user register failed"
16815
16816         wait $pid1 || error "1st user deregister failed"
16817
16818         local i
16819         local last_rec
16820         declare -A LAST_REC
16821         for i in $(seq $MDSCOUNT); do
16822                 if changelog_users mds$i | grep "^cl"; then
16823                         # make sure new records are added with one user present
16824                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16825                                           awk '/^current.index:/ { print $NF }')
16826                 else
16827                         error "mds$i has no user registered"
16828                 fi
16829         done
16830
16831         # generate more changelog records to accumulate on each MDT
16832         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16833                 error "create $DIR/$tdir/${tfile}bis failed"
16834
16835         for i in $(seq $MDSCOUNT); do
16836                 last_rec=$(changelog_users $SINGLEMDS |
16837                            awk '/^current.index:/ { print $NF }')
16838                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16839                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16840                         error "changelogs are off on mds$i"
16841         done
16842 }
16843 run_test 160i "changelog user register/unregister race"
16844
16845 test_160j() {
16846         remote_mds_nodsh && skip "remote MDS with nodsh"
16847         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16848                 skip "Need MDS version at least 2.12.56"
16849
16850         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16851         stack_trap "umount $MOUNT2" EXIT
16852
16853         changelog_register || error "first changelog_register failed"
16854         stack_trap "changelog_deregister" EXIT
16855
16856         # generate some changelog
16857         # use all_char because created files should be evenly distributed
16858         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16859                 error "mkdir $tdir failed"
16860         for ((i = 0; i < MDSCOUNT; i++)); do
16861                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16862                         error "create $DIR/$tdir/d$i.1 failed"
16863         done
16864
16865         # open the changelog device
16866         exec 3>/dev/changelog-$FSNAME-MDT0000
16867         stack_trap "exec 3>&-" EXIT
16868         exec 4</dev/changelog-$FSNAME-MDT0000
16869         stack_trap "exec 4<&-" EXIT
16870
16871         # umount the first lustre mount
16872         umount $MOUNT
16873         stack_trap "mount_client $MOUNT" EXIT
16874
16875         # read changelog, which may or may not fail, but should not crash
16876         cat <&4 >/dev/null
16877
16878         # clear changelog
16879         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16880         changelog_users $SINGLEMDS | grep -q $cl_user ||
16881                 error "User $cl_user not found in changelog_users"
16882
16883         printf 'clear:'$cl_user':0' >&3
16884 }
16885 run_test 160j "client can be umounted while its chanangelog is being used"
16886
16887 test_160k() {
16888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16889         remote_mds_nodsh && skip "remote MDS with nodsh"
16890
16891         mkdir -p $DIR/$tdir/1/1
16892
16893         changelog_register || error "changelog_register failed"
16894         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16895
16896         changelog_users $SINGLEMDS | grep -q $cl_user ||
16897                 error "User '$cl_user' not found in changelog_users"
16898 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16899         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16900         rmdir $DIR/$tdir/1/1 & sleep 1
16901         mkdir $DIR/$tdir/2
16902         touch $DIR/$tdir/2/2
16903         rm -rf $DIR/$tdir/2
16904
16905         wait
16906         sleep 4
16907
16908         changelog_dump | grep rmdir || error "rmdir not recorded"
16909 }
16910 run_test 160k "Verify that changelog records are not lost"
16911
16912 # Verifies that a file passed as a parameter has recently had an operation
16913 # performed on it that has generated an MTIME changelog which contains the
16914 # correct parent FID. As files might reside on a different MDT from the
16915 # parent directory in DNE configurations, the FIDs are translated to paths
16916 # before being compared, which should be identical
16917 compare_mtime_changelog() {
16918         local file="${1}"
16919         local mdtidx
16920         local mtime
16921         local cl_fid
16922         local pdir
16923         local dir
16924
16925         mdtidx=$($LFS getstripe --mdt-index $file)
16926         mdtidx=$(printf "%04x" $mdtidx)
16927
16928         # Obtain the parent FID from the MTIME changelog
16929         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16930         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16931
16932         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16933         [ -z "$cl_fid" ] && error "parent FID not present"
16934
16935         # Verify that the path for the parent FID is the same as the path for
16936         # the test directory
16937         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16938
16939         dir=$(dirname $1)
16940
16941         [[ "${pdir%/}" == "$dir" ]] ||
16942                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16943 }
16944
16945 test_160l() {
16946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16947
16948         remote_mds_nodsh && skip "remote MDS with nodsh"
16949         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16950                 skip "Need MDS version at least 2.13.55"
16951
16952         local cl_user
16953
16954         changelog_register || error "changelog_register failed"
16955         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16956
16957         changelog_users $SINGLEMDS | grep -q $cl_user ||
16958                 error "User '$cl_user' not found in changelog_users"
16959
16960         # Clear some types so that MTIME changelogs are generated
16961         changelog_chmask "-CREAT"
16962         changelog_chmask "-CLOSE"
16963
16964         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16965
16966         # Test CL_MTIME during setattr
16967         touch $DIR/$tdir/$tfile
16968         compare_mtime_changelog $DIR/$tdir/$tfile
16969
16970         # Test CL_MTIME during close
16971         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16972         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16973 }
16974 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16975
16976 test_160m() {
16977         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16978         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16979                 skip "Need MDS version at least 2.14.51"
16980         local cl_users
16981         local cl_user1
16982         local cl_user2
16983         local pid1
16984
16985         # Create a user
16986         changelog_register || error "first changelog_register failed"
16987         changelog_register || error "second changelog_register failed"
16988
16989         cl_users=(${CL_USERS[mds1]})
16990         cl_user1="${cl_users[0]}"
16991         cl_user2="${cl_users[1]}"
16992         # generate some changelog records to accumulate on MDT0
16993         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16994         createmany -m $DIR/$tdir/$tfile 50 ||
16995                 error "create $DIR/$tdir/$tfile failed"
16996         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16997         rm -f $DIR/$tdir
16998
16999         # check changelogs have been generated
17000         local nbcl=$(changelog_dump | wc -l)
17001         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17002
17003 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17004         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17005
17006         __changelog_clear mds1 $cl_user1 +10
17007         __changelog_clear mds1 $cl_user2 0 &
17008         pid1=$!
17009         sleep 2
17010         __changelog_clear mds1 $cl_user1 0 ||
17011                 error "fail to cancel record for $cl_user1"
17012         wait $pid1
17013         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17014 }
17015 run_test 160m "Changelog clear race"
17016
17017 test_160n() {
17018         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17019         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17020                 skip "Need MDS version at least 2.14.51"
17021         local cl_users
17022         local cl_user1
17023         local cl_user2
17024         local pid1
17025         local first_rec
17026         local last_rec=0
17027
17028         # Create a user
17029         changelog_register || error "first changelog_register failed"
17030
17031         cl_users=(${CL_USERS[mds1]})
17032         cl_user1="${cl_users[0]}"
17033
17034         # generate some changelog records to accumulate on MDT0
17035         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17036         first_rec=$(changelog_users $SINGLEMDS |
17037                         awk '/^current.index:/ { print $NF }')
17038         while (( last_rec < (( first_rec + 65000)) )); do
17039                 createmany -m $DIR/$tdir/$tfile 10000 ||
17040                         error "create $DIR/$tdir/$tfile failed"
17041
17042                 for i in $(seq 0 10000); do
17043                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17044                                 > /dev/null
17045                 done
17046
17047                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17048                         error "unlinkmany failed unlink"
17049                 last_rec=$(changelog_users $SINGLEMDS |
17050                         awk '/^current.index:/ { print $NF }')
17051                 echo last record $last_rec
17052                 (( last_rec == 0 )) && error "no changelog found"
17053         done
17054
17055 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17056         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17057
17058         __changelog_clear mds1 $cl_user1 0 &
17059         pid1=$!
17060         sleep 2
17061         __changelog_clear mds1 $cl_user1 0 ||
17062                 error "fail to cancel record for $cl_user1"
17063         wait $pid1
17064         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17065 }
17066 run_test 160n "Changelog destroy race"
17067
17068 test_160o() {
17069         local mdt="$(facet_svc $SINGLEMDS)"
17070
17071         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17072         remote_mds_nodsh && skip "remote MDS with nodsh"
17073         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17074                 skip "Need MDS version at least 2.14.52"
17075
17076         changelog_register --user test_160o -m unlnk+close+open ||
17077                 error "changelog_register failed"
17078
17079         do_facet $SINGLEMDS $LCTL --device $mdt \
17080                                 changelog_register -u "Tt3_-#" &&
17081                 error "bad symbols in name should fail"
17082
17083         do_facet $SINGLEMDS $LCTL --device $mdt \
17084                                 changelog_register -u test_160o &&
17085                 error "the same name registration should fail"
17086
17087         do_facet $SINGLEMDS $LCTL --device $mdt \
17088                         changelog_register -u test_160toolongname &&
17089                 error "too long name registration should fail"
17090
17091         changelog_chmask "MARK+HSM"
17092         lctl get_param mdd.*.changelog*mask
17093         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17094         changelog_users $SINGLEMDS | grep -q $cl_user ||
17095                 error "User $cl_user not found in changelog_users"
17096         #verify username
17097         echo $cl_user | grep -q test_160o ||
17098                 error "User $cl_user has no specific name 'test160o'"
17099
17100         # change something
17101         changelog_clear 0 || error "changelog_clear failed"
17102         # generate some changelog records to accumulate on MDT0
17103         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17104         touch $DIR/$tdir/$tfile                 # open 1
17105
17106         OPENS=$(changelog_dump | grep -c "OPEN")
17107         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17108
17109         # must be no MKDIR it wasn't set as user mask
17110         MKDIR=$(changelog_dump | grep -c "MKDIR")
17111         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17112
17113         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17114                                 mdd.$mdt.changelog_current_mask -n)
17115         # register maskless user
17116         changelog_register || error "changelog_register failed"
17117         # effective mask should be not changed because it is not minimal
17118         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17119                                 mdd.$mdt.changelog_current_mask -n)
17120         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17121         # set server mask to minimal value
17122         changelog_chmask "MARK"
17123         # check effective mask again, should be treated as DEFMASK now
17124         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17125                                 mdd.$mdt.changelog_current_mask -n)
17126         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17127
17128         do_facet $SINGLEMDS $LCTL --device $mdt \
17129                                 changelog_deregister -u test_160o ||
17130                 error "cannot deregister by name"
17131 }
17132 run_test 160o "changelog user name and mask"
17133
17134 test_160p() {
17135         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17136         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17137                 skip "Need MDS version at least 2.14.51"
17138         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17139         local cl_users
17140         local cl_user1
17141         local entry_count
17142
17143         # Create a user
17144         changelog_register || error "first changelog_register failed"
17145
17146         cl_users=(${CL_USERS[mds1]})
17147         cl_user1="${cl_users[0]}"
17148
17149         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17150         createmany -m $DIR/$tdir/$tfile 50 ||
17151                 error "create $DIR/$tdir/$tfile failed"
17152         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17153         rm -rf $DIR/$tdir
17154
17155         # check changelogs have been generated
17156         entry_count=$(changelog_dump | wc -l)
17157         ((entry_count != 0)) || error "no changelog entries found"
17158
17159         # remove changelog_users and check that orphan entries are removed
17160         stop mds1
17161         local dev=$(mdsdevname 1)
17162         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17163         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17164         entry_count=$(changelog_dump | wc -l)
17165         ((entry_count == 0)) ||
17166                 error "found $entry_count changelog entries, expected none"
17167 }
17168 run_test 160p "Changelog orphan cleanup with no users"
17169
17170 test_160q() {
17171         local mdt="$(facet_svc $SINGLEMDS)"
17172         local clu
17173
17174         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17175         remote_mds_nodsh && skip "remote MDS with nodsh"
17176         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17177                 skip "Need MDS version at least 2.14.54"
17178
17179         # set server mask to minimal value like server init does
17180         changelog_chmask "MARK"
17181         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17182                 error "changelog_register failed"
17183         # check effective mask again, should be treated as DEFMASK now
17184         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17185                                 mdd.$mdt.changelog_current_mask -n)
17186         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17187                 error "changelog_deregister failed"
17188         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17189 }
17190 run_test 160q "changelog effective mask is DEFMASK if not set"
17191
17192 test_160s() {
17193         remote_mds_nodsh && skip "remote MDS with nodsh"
17194         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17195                 skip "Need MDS version at least 2.14.55"
17196
17197         local mdts=$(comma_list $(mdts_nodes))
17198
17199         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17200         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17201                                        fail_val=$((24 * 3600 * 10))
17202
17203         # Create a user which is 10 days old
17204         changelog_register || error "first changelog_register failed"
17205         local cl_users
17206         declare -A cl_user1
17207         local i
17208
17209         # generate some changelog records to accumulate on each MDT
17210         # use all_char because created files should be evenly distributed
17211         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17212                 error "test_mkdir $tdir failed"
17213         for ((i = 0; i < MDSCOUNT; i++)); do
17214                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17215                         error "create $DIR/$tdir/d$i.1 failed"
17216         done
17217
17218         # check changelogs have been generated
17219         local nbcl=$(changelog_dump | wc -l)
17220         (( nbcl > 0 )) || error "no changelogs found"
17221
17222         # reduce the max_idle_indexes value to make sure we exceed it
17223         for param in "changelog_max_idle_indexes=2097446912" \
17224                      "changelog_max_idle_time=2592000" \
17225                      "changelog_gc=1" \
17226                      "changelog_min_gc_interval=2"; do
17227                 local MDT0=$(facet_svc $SINGLEMDS)
17228                 local var="${param%=*}"
17229                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17230
17231                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17232                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17233                         error "unable to set mdd.*.$param"
17234         done
17235
17236         local start=$SECONDS
17237         for i in $(seq $MDSCOUNT); do
17238                 cl_users=(${CL_USERS[mds$i]})
17239                 cl_user1[mds$i]="${cl_users[0]}"
17240
17241                 [[ -n "${cl_user1[mds$i]}" ]] ||
17242                         error "mds$i: no user registered"
17243         done
17244
17245         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17246         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17247
17248         # ensure we are past the previous changelog_min_gc_interval set above
17249         local sleep2=$((start + 2 - SECONDS))
17250         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17251
17252         # Generate one more changelog to trigger GC
17253         for ((i = 0; i < MDSCOUNT; i++)); do
17254                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17255                         error "create $DIR/$tdir/d$i.3 failed"
17256         done
17257
17258         # ensure gc thread is done
17259         for node in $(mdts_nodes); do
17260                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17261                         error "$node: GC-thread not done"
17262         done
17263
17264         do_nodes $mdts $LCTL set_param fail_loc=0
17265
17266         for (( i = 1; i <= MDSCOUNT; i++ )); do
17267                 # check cl_user1 is purged
17268                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17269                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17270         done
17271         return 0
17272 }
17273 run_test 160s "changelog garbage collect on idle records * time"
17274
17275 test_160t() {
17276         remote_mds_nodsh && skip "remote MDS with nodsh"
17277         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17278                 skip "Need MDS version at least 2.15.50"
17279
17280         local MDT0=$(facet_svc $SINGLEMDS)
17281         local cl_users
17282         local cl_user1
17283         local cl_user2
17284         local start
17285
17286         changelog_register --user user1 -m all ||
17287                 error "user1 failed to register"
17288
17289         mkdir_on_mdt0 $DIR/$tdir
17290         # create default overstripe to maximize changelog size
17291         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17292         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17293         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17294
17295         # user2 consumes less records so less space
17296         changelog_register --user user2 || error "user2 failed to register"
17297         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17298         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17299
17300         # check changelogs have been generated
17301         local nbcl=$(changelog_dump | wc -l)
17302         (( nbcl > 0 )) || error "no changelogs found"
17303
17304         # reduce the changelog_min_gc_interval to force check
17305         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17306                 local var="${param%=*}"
17307                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17308
17309                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17310                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17311                         error "unable to set mdd.*.$param"
17312         done
17313
17314         start=$SECONDS
17315         cl_users=(${CL_USERS[mds1]})
17316         cl_user1="${cl_users[0]}"
17317         cl_user2="${cl_users[1]}"
17318
17319         [[ -n $cl_user1 ]] ||
17320                 error "mds1: user #1 isn't registered"
17321         [[ -n $cl_user2 ]] ||
17322                 error "mds1: user #2 isn't registered"
17323
17324         # ensure we are past the previous changelog_min_gc_interval set above
17325         local sleep2=$((start + 2 - SECONDS))
17326         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17327
17328         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17329         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17330                         fail_val=$(((llog_size1 + llog_size2) / 2))
17331
17332         # Generate more changelog to trigger GC
17333         createmany -o $DIR/$tdir/u3_ 4 ||
17334                 error "create failed for more files"
17335
17336         # ensure gc thread is done
17337         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17338                 error "mds1: GC-thread not done"
17339
17340         do_facet mds1 $LCTL set_param fail_loc=0
17341
17342         # check cl_user1 is purged
17343         changelog_users mds1 | grep -q "$cl_user1" &&
17344                 error "User $cl_user1 is registered"
17345         # check cl_user2 is not purged
17346         changelog_users mds1 | grep -q "$cl_user2" ||
17347                 error "User $cl_user2 is not registered"
17348 }
17349 run_test 160t "changelog garbage collect on lack of space"
17350
17351 test_161a() {
17352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17353
17354         test_mkdir -c1 $DIR/$tdir
17355         cp /etc/hosts $DIR/$tdir/$tfile
17356         test_mkdir -c1 $DIR/$tdir/foo1
17357         test_mkdir -c1 $DIR/$tdir/foo2
17358         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17359         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17360         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17361         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17362         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17363         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17364                 $LFS fid2path $DIR $FID
17365                 error "bad link ea"
17366         fi
17367         # middle
17368         rm $DIR/$tdir/foo2/zachary
17369         # last
17370         rm $DIR/$tdir/foo2/thor
17371         # first
17372         rm $DIR/$tdir/$tfile
17373         # rename
17374         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17375         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17376                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17377         rm $DIR/$tdir/foo2/maggie
17378
17379         # overflow the EA
17380         local longname=$tfile.avg_len_is_thirty_two_
17381         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17382                 error_noexit 'failed to unlink many hardlinks'" EXIT
17383         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17384                 error "failed to hardlink many files"
17385         links=$($LFS fid2path $DIR $FID | wc -l)
17386         echo -n "${links}/1000 links in link EA"
17387         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17388 }
17389 run_test 161a "link ea sanity"
17390
17391 test_161b() {
17392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17393         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17394
17395         local MDTIDX=1
17396         local remote_dir=$DIR/$tdir/remote_dir
17397
17398         mkdir -p $DIR/$tdir
17399         $LFS mkdir -i $MDTIDX $remote_dir ||
17400                 error "create remote directory failed"
17401
17402         cp /etc/hosts $remote_dir/$tfile
17403         mkdir -p $remote_dir/foo1
17404         mkdir -p $remote_dir/foo2
17405         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17406         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17407         ln $remote_dir/$tfile $remote_dir/foo1/luna
17408         ln $remote_dir/$tfile $remote_dir/foo2/thor
17409
17410         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17411                      tr -d ']')
17412         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17413                 $LFS fid2path $DIR $FID
17414                 error "bad link ea"
17415         fi
17416         # middle
17417         rm $remote_dir/foo2/zachary
17418         # last
17419         rm $remote_dir/foo2/thor
17420         # first
17421         rm $remote_dir/$tfile
17422         # rename
17423         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17424         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17425         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17426                 $LFS fid2path $DIR $FID
17427                 error "bad link rename"
17428         fi
17429         rm $remote_dir/foo2/maggie
17430
17431         # overflow the EA
17432         local longname=filename_avg_len_is_thirty_two_
17433         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17434                 error "failed to hardlink many files"
17435         links=$($LFS fid2path $DIR $FID | wc -l)
17436         echo -n "${links}/1000 links in link EA"
17437         [[ ${links} -gt 60 ]] ||
17438                 error "expected at least 60 links in link EA"
17439         unlinkmany $remote_dir/foo2/$longname 1000 ||
17440         error "failed to unlink many hardlinks"
17441 }
17442 run_test 161b "link ea sanity under remote directory"
17443
17444 test_161c() {
17445         remote_mds_nodsh && skip "remote MDS with nodsh"
17446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17447         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17448                 skip "Need MDS version at least 2.1.5"
17449
17450         # define CLF_RENAME_LAST 0x0001
17451         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17452         changelog_register || error "changelog_register failed"
17453
17454         rm -rf $DIR/$tdir
17455         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17456         touch $DIR/$tdir/foo_161c
17457         touch $DIR/$tdir/bar_161c
17458         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17459         changelog_dump | grep RENME | tail -n 5
17460         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17461         changelog_clear 0 || error "changelog_clear failed"
17462         if [ x$flags != "x0x1" ]; then
17463                 error "flag $flags is not 0x1"
17464         fi
17465
17466         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17467         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17468         touch $DIR/$tdir/foo_161c
17469         touch $DIR/$tdir/bar_161c
17470         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17471         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17472         changelog_dump | grep RENME | tail -n 5
17473         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17474         changelog_clear 0 || error "changelog_clear failed"
17475         if [ x$flags != "x0x0" ]; then
17476                 error "flag $flags is not 0x0"
17477         fi
17478         echo "rename overwrite a target having nlink > 1," \
17479                 "changelog record has flags of $flags"
17480
17481         # rename doesn't overwrite a target (changelog flag 0x0)
17482         touch $DIR/$tdir/foo_161c
17483         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17484         changelog_dump | grep RENME | tail -n 5
17485         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17486         changelog_clear 0 || error "changelog_clear failed"
17487         if [ x$flags != "x0x0" ]; then
17488                 error "flag $flags is not 0x0"
17489         fi
17490         echo "rename doesn't overwrite a target," \
17491                 "changelog record has flags of $flags"
17492
17493         # define CLF_UNLINK_LAST 0x0001
17494         # unlink a file having nlink = 1 (changelog flag 0x1)
17495         rm -f $DIR/$tdir/foo2_161c
17496         changelog_dump | grep UNLNK | tail -n 5
17497         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17498         changelog_clear 0 || error "changelog_clear failed"
17499         if [ x$flags != "x0x1" ]; then
17500                 error "flag $flags is not 0x1"
17501         fi
17502         echo "unlink a file having nlink = 1," \
17503                 "changelog record has flags of $flags"
17504
17505         # unlink a file having nlink > 1 (changelog flag 0x0)
17506         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17507         rm -f $DIR/$tdir/foobar_161c
17508         changelog_dump | grep UNLNK | tail -n 5
17509         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17510         changelog_clear 0 || error "changelog_clear failed"
17511         if [ x$flags != "x0x0" ]; then
17512                 error "flag $flags is not 0x0"
17513         fi
17514         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17515 }
17516 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17517
17518 test_161d() {
17519         remote_mds_nodsh && skip "remote MDS with nodsh"
17520         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17521
17522         local pid
17523         local fid
17524
17525         changelog_register || error "changelog_register failed"
17526
17527         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17528         # interfer with $MOUNT/.lustre/fid/ access
17529         mkdir $DIR/$tdir
17530         [[ $? -eq 0 ]] || error "mkdir failed"
17531
17532         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17533         $LCTL set_param fail_loc=0x8000140c
17534         # 5s pause
17535         $LCTL set_param fail_val=5
17536
17537         # create file
17538         echo foofoo > $DIR/$tdir/$tfile &
17539         pid=$!
17540
17541         # wait for create to be delayed
17542         sleep 2
17543
17544         ps -p $pid
17545         [[ $? -eq 0 ]] || error "create should be blocked"
17546
17547         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17548         stack_trap "rm -f $tempfile"
17549         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17550         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17551         # some delay may occur during ChangeLog publishing and file read just
17552         # above, that could allow file write to happen finally
17553         [[ -s $tempfile ]] && echo "file should be empty"
17554
17555         $LCTL set_param fail_loc=0
17556
17557         wait $pid
17558         [[ $? -eq 0 ]] || error "create failed"
17559 }
17560 run_test 161d "create with concurrent .lustre/fid access"
17561
17562 check_path() {
17563         local expected="$1"
17564         shift
17565         local fid="$2"
17566
17567         local path
17568         path=$($LFS fid2path "$@")
17569         local rc=$?
17570
17571         if [ $rc -ne 0 ]; then
17572                 error "path looked up of '$expected' failed: rc=$rc"
17573         elif [ "$path" != "$expected" ]; then
17574                 error "path looked up '$path' instead of '$expected'"
17575         else
17576                 echo "FID '$fid' resolves to path '$path' as expected"
17577         fi
17578 }
17579
17580 test_162a() { # was test_162
17581         test_mkdir -p -c1 $DIR/$tdir/d2
17582         touch $DIR/$tdir/d2/$tfile
17583         touch $DIR/$tdir/d2/x1
17584         touch $DIR/$tdir/d2/x2
17585         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17586         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17587         # regular file
17588         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17589         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17590
17591         # softlink
17592         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17593         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17594         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17595
17596         # softlink to wrong file
17597         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17598         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17599         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17600
17601         # hardlink
17602         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17603         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17604         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17605         # fid2path dir/fsname should both work
17606         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17607         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17608
17609         # hardlink count: check that there are 2 links
17610         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17611         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17612
17613         # hardlink indexing: remove the first link
17614         rm $DIR/$tdir/d2/p/q/r/hlink
17615         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17616 }
17617 run_test 162a "path lookup sanity"
17618
17619 test_162b() {
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17622
17623         mkdir $DIR/$tdir
17624         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17625                                 error "create striped dir failed"
17626
17627         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17628                                         tail -n 1 | awk '{print $2}')
17629         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17630
17631         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17632         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17633
17634         # regular file
17635         for ((i=0;i<5;i++)); do
17636                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17637                         error "get fid for f$i failed"
17638                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17639
17640                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17641                         error "get fid for d$i failed"
17642                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17643         done
17644
17645         return 0
17646 }
17647 run_test 162b "striped directory path lookup sanity"
17648
17649 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17650 test_162c() {
17651         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17652                 skip "Need MDS version at least 2.7.51"
17653
17654         local lpath=$tdir.local
17655         local rpath=$tdir.remote
17656
17657         test_mkdir $DIR/$lpath
17658         test_mkdir $DIR/$rpath
17659
17660         for ((i = 0; i <= 101; i++)); do
17661                 lpath="$lpath/$i"
17662                 mkdir $DIR/$lpath
17663                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17664                         error "get fid for local directory $DIR/$lpath failed"
17665                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17666
17667                 rpath="$rpath/$i"
17668                 test_mkdir $DIR/$rpath
17669                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17670                         error "get fid for remote directory $DIR/$rpath failed"
17671                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17672         done
17673
17674         return 0
17675 }
17676 run_test 162c "fid2path works with paths 100 or more directories deep"
17677
17678 oalr_event_count() {
17679         local event="${1}"
17680         local trace="${2}"
17681
17682         awk -v name="${FSNAME}-OST0000" \
17683             -v event="${event}" \
17684             '$1 == "TRACE" && $2 == event && $3 == name' \
17685             "${trace}" |
17686         wc -l
17687 }
17688
17689 oalr_expect_event_count() {
17690         local event="${1}"
17691         local trace="${2}"
17692         local expect="${3}"
17693         local count
17694
17695         count=$(oalr_event_count "${event}" "${trace}")
17696         if ((count == expect)); then
17697                 return 0
17698         fi
17699
17700         error_noexit "${event} event count was '${count}', expected ${expect}"
17701         cat "${trace}" >&2
17702         exit 1
17703 }
17704
17705 cleanup_165() {
17706         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17707         stop ost1
17708         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17709 }
17710
17711 setup_165() {
17712         sync # Flush previous IOs so we can count log entries.
17713         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17714         stack_trap cleanup_165 EXIT
17715 }
17716
17717 test_165a() {
17718         local trace="/tmp/${tfile}.trace"
17719         local rc
17720         local count
17721
17722         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17723                 skip "OFD access log unsupported"
17724
17725         setup_165
17726         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17727         sleep 5
17728
17729         do_facet ost1 ofd_access_log_reader --list
17730         stop ost1
17731
17732         do_facet ost1 killall -TERM ofd_access_log_reader
17733         wait
17734         rc=$?
17735
17736         if ((rc != 0)); then
17737                 error "ofd_access_log_reader exited with rc = '${rc}'"
17738         fi
17739
17740         # Parse trace file for discovery events:
17741         oalr_expect_event_count alr_log_add "${trace}" 1
17742         oalr_expect_event_count alr_log_eof "${trace}" 1
17743         oalr_expect_event_count alr_log_free "${trace}" 1
17744 }
17745 run_test 165a "ofd access log discovery"
17746
17747 test_165b() {
17748         local trace="/tmp/${tfile}.trace"
17749         local file="${DIR}/${tfile}"
17750         local pfid1
17751         local pfid2
17752         local -a entry
17753         local rc
17754         local count
17755         local size
17756         local flags
17757
17758         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17759                 skip "OFD access log unsupported"
17760
17761         setup_165
17762         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17763         sleep 5
17764
17765         do_facet ost1 ofd_access_log_reader --list
17766
17767         lfs setstripe -c 1 -i 0 "${file}"
17768         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17769                 error "cannot create '${file}'"
17770
17771         sleep 5
17772         do_facet ost1 killall -TERM ofd_access_log_reader
17773         wait
17774         rc=$?
17775
17776         if ((rc != 0)); then
17777                 error "ofd_access_log_reader exited with rc = '${rc}'"
17778         fi
17779
17780         oalr_expect_event_count alr_log_entry "${trace}" 1
17781
17782         pfid1=$($LFS path2fid "${file}")
17783
17784         # 1     2             3   4    5     6   7    8    9     10
17785         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17786         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17787
17788         echo "entry = '${entry[*]}'" >&2
17789
17790         pfid2=${entry[4]}
17791         if [[ "${pfid1}" != "${pfid2}" ]]; then
17792                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17793         fi
17794
17795         size=${entry[8]}
17796         if ((size != 1048576)); then
17797                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17798         fi
17799
17800         flags=${entry[10]}
17801         if [[ "${flags}" != "w" ]]; then
17802                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17803         fi
17804
17805         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17806         sleep 5
17807
17808         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17809                 error "cannot read '${file}'"
17810         sleep 5
17811
17812         do_facet ost1 killall -TERM ofd_access_log_reader
17813         wait
17814         rc=$?
17815
17816         if ((rc != 0)); then
17817                 error "ofd_access_log_reader exited with rc = '${rc}'"
17818         fi
17819
17820         oalr_expect_event_count alr_log_entry "${trace}" 1
17821
17822         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17823         echo "entry = '${entry[*]}'" >&2
17824
17825         pfid2=${entry[4]}
17826         if [[ "${pfid1}" != "${pfid2}" ]]; then
17827                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17828         fi
17829
17830         size=${entry[8]}
17831         if ((size != 524288)); then
17832                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17833         fi
17834
17835         flags=${entry[10]}
17836         if [[ "${flags}" != "r" ]]; then
17837                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17838         fi
17839 }
17840 run_test 165b "ofd access log entries are produced and consumed"
17841
17842 test_165c() {
17843         local trace="/tmp/${tfile}.trace"
17844         local file="${DIR}/${tdir}/${tfile}"
17845
17846         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17847                 skip "OFD access log unsupported"
17848
17849         test_mkdir "${DIR}/${tdir}"
17850
17851         setup_165
17852         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17853         sleep 5
17854
17855         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17856
17857         # 4096 / 64 = 64. Create twice as many entries.
17858         for ((i = 0; i < 128; i++)); do
17859                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17860                         error "cannot create file"
17861         done
17862
17863         sync
17864
17865         do_facet ost1 killall -TERM ofd_access_log_reader
17866         wait
17867         rc=$?
17868         if ((rc != 0)); then
17869                 error "ofd_access_log_reader exited with rc = '${rc}'"
17870         fi
17871
17872         unlinkmany  "${file}-%d" 128
17873 }
17874 run_test 165c "full ofd access logs do not block IOs"
17875
17876 oal_get_read_count() {
17877         local stats="$1"
17878
17879         # STATS lustre-OST0001 alr_read_count 1
17880
17881         do_facet ost1 cat "${stats}" |
17882         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17883              END { print count; }'
17884 }
17885
17886 oal_expect_read_count() {
17887         local stats="$1"
17888         local count
17889         local expect="$2"
17890
17891         # Ask ofd_access_log_reader to write stats.
17892         do_facet ost1 killall -USR1 ofd_access_log_reader
17893
17894         # Allow some time for things to happen.
17895         sleep 1
17896
17897         count=$(oal_get_read_count "${stats}")
17898         if ((count == expect)); then
17899                 return 0
17900         fi
17901
17902         error_noexit "bad read count, got ${count}, expected ${expect}"
17903         do_facet ost1 cat "${stats}" >&2
17904         exit 1
17905 }
17906
17907 test_165d() {
17908         local stats="/tmp/${tfile}.stats"
17909         local file="${DIR}/${tdir}/${tfile}"
17910         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17911
17912         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17913                 skip "OFD access log unsupported"
17914
17915         test_mkdir "${DIR}/${tdir}"
17916
17917         setup_165
17918         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17919         sleep 5
17920
17921         lfs setstripe -c 1 -i 0 "${file}"
17922
17923         do_facet ost1 lctl set_param "${param}=rw"
17924         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17925                 error "cannot create '${file}'"
17926         oal_expect_read_count "${stats}" 1
17927
17928         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17929                 error "cannot read '${file}'"
17930         oal_expect_read_count "${stats}" 2
17931
17932         do_facet ost1 lctl set_param "${param}=r"
17933         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17934                 error "cannot create '${file}'"
17935         oal_expect_read_count "${stats}" 2
17936
17937         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17938                 error "cannot read '${file}'"
17939         oal_expect_read_count "${stats}" 3
17940
17941         do_facet ost1 lctl set_param "${param}=w"
17942         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17943                 error "cannot create '${file}'"
17944         oal_expect_read_count "${stats}" 4
17945
17946         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17947                 error "cannot read '${file}'"
17948         oal_expect_read_count "${stats}" 4
17949
17950         do_facet ost1 lctl set_param "${param}=0"
17951         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17952                 error "cannot create '${file}'"
17953         oal_expect_read_count "${stats}" 4
17954
17955         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17956                 error "cannot read '${file}'"
17957         oal_expect_read_count "${stats}" 4
17958
17959         do_facet ost1 killall -TERM ofd_access_log_reader
17960         wait
17961         rc=$?
17962         if ((rc != 0)); then
17963                 error "ofd_access_log_reader exited with rc = '${rc}'"
17964         fi
17965 }
17966 run_test 165d "ofd_access_log mask works"
17967
17968 test_165e() {
17969         local stats="/tmp/${tfile}.stats"
17970         local file0="${DIR}/${tdir}-0/${tfile}"
17971         local file1="${DIR}/${tdir}-1/${tfile}"
17972
17973         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17974                 skip "OFD access log unsupported"
17975
17976         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17977
17978         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17979         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17980
17981         lfs setstripe -c 1 -i 0 "${file0}"
17982         lfs setstripe -c 1 -i 0 "${file1}"
17983
17984         setup_165
17985         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17986         sleep 5
17987
17988         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17989                 error "cannot create '${file0}'"
17990         sync
17991         oal_expect_read_count "${stats}" 0
17992
17993         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17994                 error "cannot create '${file1}'"
17995         sync
17996         oal_expect_read_count "${stats}" 1
17997
17998         do_facet ost1 killall -TERM ofd_access_log_reader
17999         wait
18000         rc=$?
18001         if ((rc != 0)); then
18002                 error "ofd_access_log_reader exited with rc = '${rc}'"
18003         fi
18004 }
18005 run_test 165e "ofd_access_log MDT index filter works"
18006
18007 test_165f() {
18008         local trace="/tmp/${tfile}.trace"
18009         local rc
18010         local count
18011
18012         setup_165
18013         do_facet ost1 timeout 60 ofd_access_log_reader \
18014                 --exit-on-close --debug=- --trace=- > "${trace}" &
18015         sleep 5
18016         stop ost1
18017
18018         wait
18019         rc=$?
18020
18021         if ((rc != 0)); then
18022                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18023                 cat "${trace}"
18024                 exit 1
18025         fi
18026 }
18027 run_test 165f "ofd_access_log_reader --exit-on-close works"
18028
18029 test_169() {
18030         # do directio so as not to populate the page cache
18031         log "creating a 10 Mb file"
18032         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18033                 error "multiop failed while creating a file"
18034         log "starting reads"
18035         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18036         log "truncating the file"
18037         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18038                 error "multiop failed while truncating the file"
18039         log "killing dd"
18040         kill %+ || true # reads might have finished
18041         echo "wait until dd is finished"
18042         wait
18043         log "removing the temporary file"
18044         rm -rf $DIR/$tfile || error "tmp file removal failed"
18045 }
18046 run_test 169 "parallel read and truncate should not deadlock"
18047
18048 test_170() {
18049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18050
18051         $LCTL clear     # bug 18514
18052         $LCTL debug_daemon start $TMP/${tfile}_log_good
18053         touch $DIR/$tfile
18054         $LCTL debug_daemon stop
18055         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18056                 error "sed failed to read log_good"
18057
18058         $LCTL debug_daemon start $TMP/${tfile}_log_good
18059         rm -rf $DIR/$tfile
18060         $LCTL debug_daemon stop
18061
18062         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18063                error "lctl df log_bad failed"
18064
18065         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18066         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18067
18068         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18069         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18070
18071         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18072                 error "bad_line good_line1 good_line2 are empty"
18073
18074         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18075         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18076         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18077
18078         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18079         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18080         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18081
18082         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18083                 error "bad_line_new good_line_new are empty"
18084
18085         local expected_good=$((good_line1 + good_line2*2))
18086
18087         rm -f $TMP/${tfile}*
18088         # LU-231, short malformed line may not be counted into bad lines
18089         if [ $bad_line -ne $bad_line_new ] &&
18090                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18091                 error "expected $bad_line bad lines, but got $bad_line_new"
18092                 return 1
18093         fi
18094
18095         if [ $expected_good -ne $good_line_new ]; then
18096                 error "expected $expected_good good lines, but got $good_line_new"
18097                 return 2
18098         fi
18099         true
18100 }
18101 run_test 170 "test lctl df to handle corrupted log ====================="
18102
18103 test_171() { # bug20592
18104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18105
18106         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18107         $LCTL set_param fail_loc=0x50e
18108         $LCTL set_param fail_val=3000
18109         multiop_bg_pause $DIR/$tfile O_s || true
18110         local MULTIPID=$!
18111         kill -USR1 $MULTIPID
18112         # cause log dump
18113         sleep 3
18114         wait $MULTIPID
18115         if dmesg | grep "recursive fault"; then
18116                 error "caught a recursive fault"
18117         fi
18118         $LCTL set_param fail_loc=0
18119         true
18120 }
18121 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18122
18123 test_172() {
18124
18125         #define OBD_FAIL_OBD_CLEANUP  0x60e
18126         $LCTL set_param fail_loc=0x60e
18127         umount $MOUNT || error "umount $MOUNT failed"
18128         stack_trap "mount_client $MOUNT"
18129
18130         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18131                 error "no client OBDs are remained"
18132
18133         $LCTL dl | while read devno state type name foo; do
18134                 case $type in
18135                 lov|osc|lmv|mdc)
18136                         $LCTL --device $name cleanup
18137                         $LCTL --device $name detach
18138                         ;;
18139                 *)
18140                         # skip server devices
18141                         ;;
18142                 esac
18143         done
18144
18145         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18146                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18147                 error "some client OBDs are still remained"
18148         fi
18149
18150 }
18151 run_test 172 "manual device removal with lctl cleanup/detach ======"
18152
18153 # it would be good to share it with obdfilter-survey/iokit-libecho code
18154 setup_obdecho_osc () {
18155         local rc=0
18156         local ost_nid=$1
18157         local obdfilter_name=$2
18158         echo "Creating new osc for $obdfilter_name on $ost_nid"
18159         # make sure we can find loopback nid
18160         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18161
18162         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18163                            ${obdfilter_name}_osc_UUID || rc=2; }
18164         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18165                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18166         return $rc
18167 }
18168
18169 cleanup_obdecho_osc () {
18170         local obdfilter_name=$1
18171         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18172         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18173         return 0
18174 }
18175
18176 obdecho_test() {
18177         local OBD=$1
18178         local node=$2
18179         local pages=${3:-64}
18180         local rc=0
18181         local id
18182
18183         local count=10
18184         local obd_size=$(get_obd_size $node $OBD)
18185         local page_size=$(get_page_size $node)
18186         if [[ -n "$obd_size" ]]; then
18187                 local new_count=$((obd_size / (pages * page_size / 1024)))
18188                 [[ $new_count -ge $count ]] || count=$new_count
18189         fi
18190
18191         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18192         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18193                            rc=2; }
18194         if [ $rc -eq 0 ]; then
18195             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18196             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18197         fi
18198         echo "New object id is $id"
18199         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18200                            rc=4; }
18201         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18202                            "test_brw $count w v $pages $id" || rc=4; }
18203         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18204                            rc=4; }
18205         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18206                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18207         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18208                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18209         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18210         return $rc
18211 }
18212
18213 test_180a() {
18214         skip "obdecho on osc is no longer supported"
18215 }
18216 run_test 180a "test obdecho on osc"
18217
18218 test_180b() {
18219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18220         remote_ost_nodsh && skip "remote OST with nodsh"
18221
18222         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18223                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18224                 error "failed to load module obdecho"
18225
18226         local target=$(do_facet ost1 $LCTL dl |
18227                        awk '/obdfilter/ { print $4; exit; }')
18228
18229         if [ -n "$target" ]; then
18230                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18231         else
18232                 do_facet ost1 $LCTL dl
18233                 error "there is no obdfilter target on ost1"
18234         fi
18235 }
18236 run_test 180b "test obdecho directly on obdfilter"
18237
18238 test_180c() { # LU-2598
18239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18240         remote_ost_nodsh && skip "remote OST with nodsh"
18241         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18242                 skip "Need MDS version at least 2.4.0"
18243
18244         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18245                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18246                 error "failed to load module obdecho"
18247
18248         local target=$(do_facet ost1 $LCTL dl |
18249                        awk '/obdfilter/ { print $4; exit; }')
18250
18251         if [ -n "$target" ]; then
18252                 local pages=16384 # 64MB bulk I/O RPC size
18253
18254                 obdecho_test "$target" ost1 "$pages" ||
18255                         error "obdecho_test with pages=$pages failed with $?"
18256         else
18257                 do_facet ost1 $LCTL dl
18258                 error "there is no obdfilter target on ost1"
18259         fi
18260 }
18261 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18262
18263 test_181() { # bug 22177
18264         test_mkdir $DIR/$tdir
18265         # create enough files to index the directory
18266         createmany -o $DIR/$tdir/foobar 4000
18267         # print attributes for debug purpose
18268         lsattr -d .
18269         # open dir
18270         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18271         MULTIPID=$!
18272         # remove the files & current working dir
18273         unlinkmany $DIR/$tdir/foobar 4000
18274         rmdir $DIR/$tdir
18275         kill -USR1 $MULTIPID
18276         wait $MULTIPID
18277         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18278         return 0
18279 }
18280 run_test 181 "Test open-unlinked dir ========================"
18281
18282 test_182a() {
18283         local fcount=1000
18284         local tcount=10
18285
18286         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18287
18288         $LCTL set_param mdc.*.rpc_stats=clear
18289
18290         for (( i = 0; i < $tcount; i++ )) ; do
18291                 mkdir $DIR/$tdir/$i
18292         done
18293
18294         for (( i = 0; i < $tcount; i++ )) ; do
18295                 createmany -o $DIR/$tdir/$i/f- $fcount &
18296         done
18297         wait
18298
18299         for (( i = 0; i < $tcount; i++ )) ; do
18300                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18301         done
18302         wait
18303
18304         $LCTL get_param mdc.*.rpc_stats
18305
18306         rm -rf $DIR/$tdir
18307 }
18308 run_test 182a "Test parallel modify metadata operations from mdc"
18309
18310 test_182b() {
18311         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18312         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18313         local dcount=1000
18314         local tcount=10
18315         local stime
18316         local etime
18317         local delta
18318
18319         do_facet mds1 $LCTL list_param \
18320                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18321                 skip "MDS lacks parallel RPC handling"
18322
18323         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18324
18325         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18326                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18327
18328         stime=$(date +%s)
18329         createmany -i 0 -d $DIR/$tdir/t- $tcount
18330
18331         for (( i = 0; i < $tcount; i++ )) ; do
18332                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18333         done
18334         wait
18335         etime=$(date +%s)
18336         delta=$((etime - stime))
18337         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18338
18339         stime=$(date +%s)
18340         for (( i = 0; i < $tcount; i++ )) ; do
18341                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18342         done
18343         wait
18344         etime=$(date +%s)
18345         delta=$((etime - stime))
18346         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18347
18348         rm -rf $DIR/$tdir
18349
18350         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18351
18352         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18353
18354         stime=$(date +%s)
18355         createmany -i 0 -d $DIR/$tdir/t- $tcount
18356
18357         for (( i = 0; i < $tcount; i++ )) ; do
18358                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18359         done
18360         wait
18361         etime=$(date +%s)
18362         delta=$((etime - stime))
18363         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18364
18365         stime=$(date +%s)
18366         for (( i = 0; i < $tcount; i++ )) ; do
18367                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18368         done
18369         wait
18370         etime=$(date +%s)
18371         delta=$((etime - stime))
18372         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18373
18374         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18375 }
18376 run_test 182b "Test parallel modify metadata operations from osp"
18377
18378 test_183() { # LU-2275
18379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18380         remote_mds_nodsh && skip "remote MDS with nodsh"
18381         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18382                 skip "Need MDS version at least 2.3.56"
18383
18384         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18385         echo aaa > $DIR/$tdir/$tfile
18386
18387 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18388         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18389
18390         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18391         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18392
18393         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18394
18395         # Flush negative dentry cache
18396         touch $DIR/$tdir/$tfile
18397
18398         # We are not checking for any leaked references here, they'll
18399         # become evident next time we do cleanup with module unload.
18400         rm -rf $DIR/$tdir
18401 }
18402 run_test 183 "No crash or request leak in case of strange dispositions ========"
18403
18404 # test suite 184 is for LU-2016, LU-2017
18405 test_184a() {
18406         check_swap_layouts_support
18407
18408         dir0=$DIR/$tdir/$testnum
18409         test_mkdir -p -c1 $dir0
18410         ref1=/etc/passwd
18411         ref2=/etc/group
18412         file1=$dir0/f1
18413         file2=$dir0/f2
18414         $LFS setstripe -c1 $file1
18415         cp $ref1 $file1
18416         $LFS setstripe -c2 $file2
18417         cp $ref2 $file2
18418         gen1=$($LFS getstripe -g $file1)
18419         gen2=$($LFS getstripe -g $file2)
18420
18421         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18422         gen=$($LFS getstripe -g $file1)
18423         [[ $gen1 != $gen ]] ||
18424                 error "Layout generation on $file1 does not change"
18425         gen=$($LFS getstripe -g $file2)
18426         [[ $gen2 != $gen ]] ||
18427                 error "Layout generation on $file2 does not change"
18428
18429         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18430         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18431
18432         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18433 }
18434 run_test 184a "Basic layout swap"
18435
18436 test_184b() {
18437         check_swap_layouts_support
18438
18439         dir0=$DIR/$tdir/$testnum
18440         mkdir -p $dir0 || error "creating dir $dir0"
18441         file1=$dir0/f1
18442         file2=$dir0/f2
18443         file3=$dir0/f3
18444         dir1=$dir0/d1
18445         dir2=$dir0/d2
18446         mkdir $dir1 $dir2
18447         $LFS setstripe -c1 $file1
18448         $LFS setstripe -c2 $file2
18449         $LFS setstripe -c1 $file3
18450         chown $RUNAS_ID $file3
18451         gen1=$($LFS getstripe -g $file1)
18452         gen2=$($LFS getstripe -g $file2)
18453
18454         $LFS swap_layouts $dir1 $dir2 &&
18455                 error "swap of directories layouts should fail"
18456         $LFS swap_layouts $dir1 $file1 &&
18457                 error "swap of directory and file layouts should fail"
18458         $RUNAS $LFS swap_layouts $file1 $file2 &&
18459                 error "swap of file we cannot write should fail"
18460         $LFS swap_layouts $file1 $file3 &&
18461                 error "swap of file with different owner should fail"
18462         /bin/true # to clear error code
18463 }
18464 run_test 184b "Forbidden layout swap (will generate errors)"
18465
18466 test_184c() {
18467         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18468         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18469         check_swap_layouts_support
18470         check_swap_layout_no_dom $DIR
18471
18472         local dir0=$DIR/$tdir/$testnum
18473         mkdir -p $dir0 || error "creating dir $dir0"
18474
18475         local ref1=$dir0/ref1
18476         local ref2=$dir0/ref2
18477         local file1=$dir0/file1
18478         local file2=$dir0/file2
18479         # create a file large enough for the concurrent test
18480         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18481         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18482         echo "ref file size: ref1($(stat -c %s $ref1))," \
18483              "ref2($(stat -c %s $ref2))"
18484
18485         cp $ref2 $file2
18486         dd if=$ref1 of=$file1 bs=16k &
18487         local DD_PID=$!
18488
18489         # Make sure dd starts to copy file, but wait at most 5 seconds
18490         local loops=0
18491         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18492
18493         $LFS swap_layouts $file1 $file2
18494         local rc=$?
18495         wait $DD_PID
18496         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18497         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18498
18499         # how many bytes copied before swapping layout
18500         local copied=$(stat -c %s $file2)
18501         local remaining=$(stat -c %s $ref1)
18502         remaining=$((remaining - copied))
18503         echo "Copied $copied bytes before swapping layout..."
18504
18505         cmp -n $copied $file1 $ref2 | grep differ &&
18506                 error "Content mismatch [0, $copied) of ref2 and file1"
18507         cmp -n $copied $file2 $ref1 ||
18508                 error "Content mismatch [0, $copied) of ref1 and file2"
18509         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18510                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18511
18512         # clean up
18513         rm -f $ref1 $ref2 $file1 $file2
18514 }
18515 run_test 184c "Concurrent write and layout swap"
18516
18517 test_184d() {
18518         check_swap_layouts_support
18519         check_swap_layout_no_dom $DIR
18520         [ -z "$(which getfattr 2>/dev/null)" ] &&
18521                 skip_env "no getfattr command"
18522
18523         local file1=$DIR/$tdir/$tfile-1
18524         local file2=$DIR/$tdir/$tfile-2
18525         local file3=$DIR/$tdir/$tfile-3
18526         local lovea1
18527         local lovea2
18528
18529         mkdir -p $DIR/$tdir
18530         touch $file1 || error "create $file1 failed"
18531         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18532                 error "create $file2 failed"
18533         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18534                 error "create $file3 failed"
18535         lovea1=$(get_layout_param $file1)
18536
18537         $LFS swap_layouts $file2 $file3 ||
18538                 error "swap $file2 $file3 layouts failed"
18539         $LFS swap_layouts $file1 $file2 ||
18540                 error "swap $file1 $file2 layouts failed"
18541
18542         lovea2=$(get_layout_param $file2)
18543         echo "$lovea1"
18544         echo "$lovea2"
18545         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18546
18547         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18548         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18549 }
18550 run_test 184d "allow stripeless layouts swap"
18551
18552 test_184e() {
18553         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18554                 skip "Need MDS version at least 2.6.94"
18555         check_swap_layouts_support
18556         check_swap_layout_no_dom $DIR
18557         [ -z "$(which getfattr 2>/dev/null)" ] &&
18558                 skip_env "no getfattr command"
18559
18560         local file1=$DIR/$tdir/$tfile-1
18561         local file2=$DIR/$tdir/$tfile-2
18562         local file3=$DIR/$tdir/$tfile-3
18563         local lovea
18564
18565         mkdir -p $DIR/$tdir
18566         touch $file1 || error "create $file1 failed"
18567         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18568                 error "create $file2 failed"
18569         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18570                 error "create $file3 failed"
18571
18572         $LFS swap_layouts $file1 $file2 ||
18573                 error "swap $file1 $file2 layouts failed"
18574
18575         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18576         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18577
18578         echo 123 > $file1 || error "Should be able to write into $file1"
18579
18580         $LFS swap_layouts $file1 $file3 ||
18581                 error "swap $file1 $file3 layouts failed"
18582
18583         echo 123 > $file1 || error "Should be able to write into $file1"
18584
18585         rm -rf $file1 $file2 $file3
18586 }
18587 run_test 184e "Recreate layout after stripeless layout swaps"
18588
18589 test_184f() {
18590         # Create a file with name longer than sizeof(struct stat) ==
18591         # 144 to see if we can get chars from the file name to appear
18592         # in the returned striping. Note that 'f' == 0x66.
18593         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18594
18595         mkdir -p $DIR/$tdir
18596         mcreate $DIR/$tdir/$file
18597         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18598                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18599         fi
18600 }
18601 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18602
18603 test_185() { # LU-2441
18604         # LU-3553 - no volatile file support in old servers
18605         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18606                 skip "Need MDS version at least 2.3.60"
18607
18608         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18609         touch $DIR/$tdir/spoo
18610         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18611         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18612                 error "cannot create/write a volatile file"
18613         [ "$FILESET" == "" ] &&
18614         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18615                 error "FID is still valid after close"
18616
18617         multiop_bg_pause $DIR/$tdir vVw4096_c
18618         local multi_pid=$!
18619
18620         local OLD_IFS=$IFS
18621         IFS=":"
18622         local fidv=($fid)
18623         IFS=$OLD_IFS
18624         # assume that the next FID for this client is sequential, since stdout
18625         # is unfortunately eaten by multiop_bg_pause
18626         local n=$((${fidv[1]} + 1))
18627         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18628         if [ "$FILESET" == "" ]; then
18629                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18630                         error "FID is missing before close"
18631         fi
18632         kill -USR1 $multi_pid
18633         # 1 second delay, so if mtime change we will see it
18634         sleep 1
18635         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18636         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18637 }
18638 run_test 185 "Volatile file support"
18639
18640 function create_check_volatile() {
18641         local idx=$1
18642         local tgt
18643
18644         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18645         local PID=$!
18646         sleep 1
18647         local FID=$(cat /tmp/${tfile}.fid)
18648         [ "$FID" == "" ] && error "can't get FID for volatile"
18649         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18650         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18651         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18652         kill -USR1 $PID
18653         wait
18654         sleep 1
18655         cancel_lru_locks mdc # flush opencache
18656         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18657         return 0
18658 }
18659
18660 test_185a(){
18661         # LU-12516 - volatile creation via .lustre
18662         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18663                 skip "Need MDS version at least 2.3.55"
18664
18665         create_check_volatile 0
18666         [ $MDSCOUNT -lt 2 ] && return 0
18667
18668         # DNE case
18669         create_check_volatile 1
18670
18671         return 0
18672 }
18673 run_test 185a "Volatile file creation in .lustre/fid/"
18674
18675 test_187a() {
18676         remote_mds_nodsh && skip "remote MDS with nodsh"
18677         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18678                 skip "Need MDS version at least 2.3.0"
18679
18680         local dir0=$DIR/$tdir/$testnum
18681         mkdir -p $dir0 || error "creating dir $dir0"
18682
18683         local file=$dir0/file1
18684         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18685         local dv1=$($LFS data_version $file)
18686         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18687         local dv2=$($LFS data_version $file)
18688         [[ $dv1 != $dv2 ]] ||
18689                 error "data version did not change on write $dv1 == $dv2"
18690
18691         # clean up
18692         rm -f $file1
18693 }
18694 run_test 187a "Test data version change"
18695
18696 test_187b() {
18697         remote_mds_nodsh && skip "remote MDS with nodsh"
18698         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18699                 skip "Need MDS version at least 2.3.0"
18700
18701         local dir0=$DIR/$tdir/$testnum
18702         mkdir -p $dir0 || error "creating dir $dir0"
18703
18704         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18705         [[ ${DV[0]} != ${DV[1]} ]] ||
18706                 error "data version did not change on write"\
18707                       " ${DV[0]} == ${DV[1]}"
18708
18709         # clean up
18710         rm -f $file1
18711 }
18712 run_test 187b "Test data version change on volatile file"
18713
18714 test_200() {
18715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18716         remote_mgs_nodsh && skip "remote MGS with nodsh"
18717         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18718
18719         local POOL=${POOL:-cea1}
18720         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18721         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18722         # Pool OST targets
18723         local first_ost=0
18724         local last_ost=$(($OSTCOUNT - 1))
18725         local ost_step=2
18726         local ost_list=$(seq $first_ost $ost_step $last_ost)
18727         local ost_range="$first_ost $last_ost $ost_step"
18728         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18729         local file_dir=$POOL_ROOT/file_tst
18730         local subdir=$test_path/subdir
18731         local rc=0
18732
18733         while : ; do
18734                 # former test_200a test_200b
18735                 pool_add $POOL                          || { rc=$? ; break; }
18736                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18737                 # former test_200c test_200d
18738                 mkdir -p $test_path
18739                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18740                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18741                 mkdir -p $subdir
18742                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18743                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18744                                                         || { rc=$? ; break; }
18745                 # former test_200e test_200f
18746                 local files=$((OSTCOUNT*3))
18747                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18748                                                         || { rc=$? ; break; }
18749                 pool_create_files $POOL $file_dir $files "$ost_list" \
18750                                                         || { rc=$? ; break; }
18751                 # former test_200g test_200h
18752                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18753                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18754
18755                 # former test_201a test_201b test_201c
18756                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18757
18758                 local f=$test_path/$tfile
18759                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18760                 pool_remove $POOL $f                    || { rc=$? ; break; }
18761                 break
18762         done
18763
18764         destroy_test_pools
18765
18766         return $rc
18767 }
18768 run_test 200 "OST pools"
18769
18770 # usage: default_attr <count | size | offset>
18771 default_attr() {
18772         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18773 }
18774
18775 # usage: check_default_stripe_attr
18776 check_default_stripe_attr() {
18777         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18778         case $1 in
18779         --stripe-count|-c)
18780                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18781         --stripe-size|-S)
18782                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18783         --stripe-index|-i)
18784                 EXPECTED=-1;;
18785         *)
18786                 error "unknown getstripe attr '$1'"
18787         esac
18788
18789         [ $ACTUAL == $EXPECTED ] ||
18790                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18791 }
18792
18793 test_204a() {
18794         test_mkdir $DIR/$tdir
18795         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18796
18797         check_default_stripe_attr --stripe-count
18798         check_default_stripe_attr --stripe-size
18799         check_default_stripe_attr --stripe-index
18800 }
18801 run_test 204a "Print default stripe attributes"
18802
18803 test_204b() {
18804         test_mkdir $DIR/$tdir
18805         $LFS setstripe --stripe-count 1 $DIR/$tdir
18806
18807         check_default_stripe_attr --stripe-size
18808         check_default_stripe_attr --stripe-index
18809 }
18810 run_test 204b "Print default stripe size and offset"
18811
18812 test_204c() {
18813         test_mkdir $DIR/$tdir
18814         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18815
18816         check_default_stripe_attr --stripe-count
18817         check_default_stripe_attr --stripe-index
18818 }
18819 run_test 204c "Print default stripe count and offset"
18820
18821 test_204d() {
18822         test_mkdir $DIR/$tdir
18823         $LFS setstripe --stripe-index 0 $DIR/$tdir
18824
18825         check_default_stripe_attr --stripe-count
18826         check_default_stripe_attr --stripe-size
18827 }
18828 run_test 204d "Print default stripe count and size"
18829
18830 test_204e() {
18831         test_mkdir $DIR/$tdir
18832         $LFS setstripe -d $DIR/$tdir
18833
18834         check_default_stripe_attr --stripe-count --raw
18835         check_default_stripe_attr --stripe-size --raw
18836         check_default_stripe_attr --stripe-index --raw
18837 }
18838 run_test 204e "Print raw stripe attributes"
18839
18840 test_204f() {
18841         test_mkdir $DIR/$tdir
18842         $LFS setstripe --stripe-count 1 $DIR/$tdir
18843
18844         check_default_stripe_attr --stripe-size --raw
18845         check_default_stripe_attr --stripe-index --raw
18846 }
18847 run_test 204f "Print raw stripe size and offset"
18848
18849 test_204g() {
18850         test_mkdir $DIR/$tdir
18851         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18852
18853         check_default_stripe_attr --stripe-count --raw
18854         check_default_stripe_attr --stripe-index --raw
18855 }
18856 run_test 204g "Print raw stripe count and offset"
18857
18858 test_204h() {
18859         test_mkdir $DIR/$tdir
18860         $LFS setstripe --stripe-index 0 $DIR/$tdir
18861
18862         check_default_stripe_attr --stripe-count --raw
18863         check_default_stripe_attr --stripe-size --raw
18864 }
18865 run_test 204h "Print raw stripe count and size"
18866
18867 # Figure out which job scheduler is being used, if any,
18868 # or use a fake one
18869 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18870         JOBENV=SLURM_JOB_ID
18871 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18872         JOBENV=LSB_JOBID
18873 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18874         JOBENV=PBS_JOBID
18875 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18876         JOBENV=LOADL_STEP_ID
18877 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18878         JOBENV=JOB_ID
18879 else
18880         $LCTL list_param jobid_name > /dev/null 2>&1
18881         if [ $? -eq 0 ]; then
18882                 JOBENV=nodelocal
18883         else
18884                 JOBENV=FAKE_JOBID
18885         fi
18886 fi
18887 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18888
18889 verify_jobstats() {
18890         local cmd=($1)
18891         shift
18892         local facets="$@"
18893
18894 # we don't really need to clear the stats for this test to work, since each
18895 # command has a unique jobid, but it makes debugging easier if needed.
18896 #       for facet in $facets; do
18897 #               local dev=$(convert_facet2label $facet)
18898 #               # clear old jobstats
18899 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18900 #       done
18901
18902         # use a new JobID for each test, or we might see an old one
18903         [ "$JOBENV" = "FAKE_JOBID" ] &&
18904                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18905
18906         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18907
18908         [ "$JOBENV" = "nodelocal" ] && {
18909                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18910                 $LCTL set_param jobid_name=$FAKE_JOBID
18911                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18912         }
18913
18914         log "Test: ${cmd[*]}"
18915         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18916
18917         if [ $JOBENV = "FAKE_JOBID" ]; then
18918                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18919         else
18920                 ${cmd[*]}
18921         fi
18922
18923         # all files are created on OST0000
18924         for facet in $facets; do
18925                 local stats="*.$(convert_facet2label $facet).job_stats"
18926
18927                 # strip out libtool wrappers for in-tree executables
18928                 if (( $(do_facet $facet lctl get_param $stats |
18929                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18930                         do_facet $facet lctl get_param $stats
18931                         error "No jobstats for $JOBVAL found on $facet::$stats"
18932                 fi
18933         done
18934 }
18935
18936 jobstats_set() {
18937         local new_jobenv=$1
18938
18939         set_persistent_param_and_check client "jobid_var" \
18940                 "$FSNAME.sys.jobid_var" $new_jobenv
18941 }
18942
18943 test_205a() { # Job stats
18944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18945         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18946                 skip "Need MDS version with at least 2.7.1"
18947         remote_mgs_nodsh && skip "remote MGS with nodsh"
18948         remote_mds_nodsh && skip "remote MDS with nodsh"
18949         remote_ost_nodsh && skip "remote OST with nodsh"
18950         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18951                 skip "Server doesn't support jobstats"
18952         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18953
18954         local old_jobenv=$($LCTL get_param -n jobid_var)
18955         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18956
18957         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18958                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18959         else
18960                 stack_trap "do_facet mgs $PERM_CMD \
18961                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18962         fi
18963         changelog_register
18964
18965         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18966                                 mdt.*.job_cleanup_interval | head -n 1)
18967         local new_interval=5
18968         do_facet $SINGLEMDS \
18969                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18970         stack_trap "do_facet $SINGLEMDS \
18971                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18972         local start=$SECONDS
18973
18974         local cmd
18975         # mkdir
18976         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18977         verify_jobstats "$cmd" "$SINGLEMDS"
18978         # rmdir
18979         cmd="rmdir $DIR/$tdir"
18980         verify_jobstats "$cmd" "$SINGLEMDS"
18981         # mkdir on secondary MDT
18982         if [ $MDSCOUNT -gt 1 ]; then
18983                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18984                 verify_jobstats "$cmd" "mds2"
18985         fi
18986         # mknod
18987         cmd="mknod $DIR/$tfile c 1 3"
18988         verify_jobstats "$cmd" "$SINGLEMDS"
18989         # unlink
18990         cmd="rm -f $DIR/$tfile"
18991         verify_jobstats "$cmd" "$SINGLEMDS"
18992         # create all files on OST0000 so verify_jobstats can find OST stats
18993         # open & close
18994         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18995         verify_jobstats "$cmd" "$SINGLEMDS"
18996         # setattr
18997         cmd="touch $DIR/$tfile"
18998         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18999         # write
19000         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19001         verify_jobstats "$cmd" "ost1"
19002         # read
19003         cancel_lru_locks osc
19004         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19005         verify_jobstats "$cmd" "ost1"
19006         # truncate
19007         cmd="$TRUNCATE $DIR/$tfile 0"
19008         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19009         # rename
19010         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19011         verify_jobstats "$cmd" "$SINGLEMDS"
19012         # jobstats expiry - sleep until old stats should be expired
19013         local left=$((new_interval + 5 - (SECONDS - start)))
19014         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19015                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19016                         "0" $left
19017         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19018         verify_jobstats "$cmd" "$SINGLEMDS"
19019         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19020             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19021
19022         # Ensure that jobid are present in changelog (if supported by MDS)
19023         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19024                 changelog_dump | tail -10
19025                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19026                 [ $jobids -eq 9 ] ||
19027                         error "Wrong changelog jobid count $jobids != 9"
19028
19029                 # LU-5862
19030                 JOBENV="disable"
19031                 jobstats_set $JOBENV
19032                 touch $DIR/$tfile
19033                 changelog_dump | grep $tfile
19034                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19035                 [ $jobids -eq 0 ] ||
19036                         error "Unexpected jobids when jobid_var=$JOBENV"
19037         fi
19038
19039         # test '%j' access to environment variable - if supported
19040         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19041                 JOBENV="JOBCOMPLEX"
19042                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19043
19044                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19045         fi
19046
19047         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19048                 JOBENV="JOBCOMPLEX"
19049                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19050
19051                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19052         fi
19053
19054         # test '%j' access to per-session jobid - if supported
19055         if lctl list_param jobid_this_session > /dev/null 2>&1
19056         then
19057                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19058                 lctl set_param jobid_this_session=$USER
19059
19060                 JOBENV="JOBCOMPLEX"
19061                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19062
19063                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19064         fi
19065 }
19066 run_test 205a "Verify job stats"
19067
19068 # LU-13117, LU-13597
19069 test_205b() {
19070         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19071                 skip "Need MDS version at least 2.13.54.91"
19072
19073         local job_stats="mdt.*.job_stats"
19074         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19075
19076         do_facet mds1 $LCTL set_param $job_stats=clear
19077
19078         # Setting jobid_var to USER might not be supported
19079         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19080         $LCTL set_param jobid_var=USER || true
19081         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19082         $LCTL set_param jobid_name="%j.%e.%u"
19083
19084         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19085         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19086                 { do_facet mds1 $LCTL get_param $job_stats;
19087                   error "Unexpected jobid found"; }
19088         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19089                 { do_facet mds1 $LCTL get_param $job_stats;
19090                   error "wrong job_stats format found"; }
19091
19092         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19093                 echo "MDS does not yet escape jobid" && return 0
19094         $LCTL set_param jobid_var=TEST205b
19095         env -i TEST205b="has sp" touch $DIR/$tfile.2
19096         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19097                 { do_facet mds1 $LCTL get_param $job_stats;
19098                   error "jobid not escaped"; }
19099 }
19100 run_test 205b "Verify job stats jobid and output format"
19101
19102 # LU-13733
19103 test_205c() {
19104         $LCTL set_param llite.*.stats=0
19105         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19106         $LCTL get_param llite.*.stats
19107         $LCTL get_param llite.*.stats | grep \
19108                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19109                         error "wrong client stats format found"
19110 }
19111 run_test 205c "Verify client stats format"
19112
19113 # LU-1480, LU-1773 and LU-1657
19114 test_206() {
19115         mkdir -p $DIR/$tdir
19116         $LFS setstripe -c -1 $DIR/$tdir
19117 #define OBD_FAIL_LOV_INIT 0x1403
19118         $LCTL set_param fail_loc=0xa0001403
19119         $LCTL set_param fail_val=1
19120         touch $DIR/$tdir/$tfile || true
19121 }
19122 run_test 206 "fail lov_init_raid0() doesn't lbug"
19123
19124 test_207a() {
19125         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19126         local fsz=`stat -c %s $DIR/$tfile`
19127         cancel_lru_locks mdc
19128
19129         # do not return layout in getattr intent
19130 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19131         $LCTL set_param fail_loc=0x170
19132         local sz=`stat -c %s $DIR/$tfile`
19133
19134         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19135
19136         rm -rf $DIR/$tfile
19137 }
19138 run_test 207a "can refresh layout at glimpse"
19139
19140 test_207b() {
19141         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19142         local cksum=`md5sum $DIR/$tfile`
19143         local fsz=`stat -c %s $DIR/$tfile`
19144         cancel_lru_locks mdc
19145         cancel_lru_locks osc
19146
19147         # do not return layout in getattr intent
19148 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19149         $LCTL set_param fail_loc=0x171
19150
19151         # it will refresh layout after the file is opened but before read issues
19152         echo checksum is "$cksum"
19153         echo "$cksum" |md5sum -c --quiet || error "file differs"
19154
19155         rm -rf $DIR/$tfile
19156 }
19157 run_test 207b "can refresh layout at open"
19158
19159 test_208() {
19160         # FIXME: in this test suite, only RD lease is used. This is okay
19161         # for now as only exclusive open is supported. After generic lease
19162         # is done, this test suite should be revised. - Jinshan
19163
19164         remote_mds_nodsh && skip "remote MDS with nodsh"
19165         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19166                 skip "Need MDS version at least 2.4.52"
19167
19168         echo "==== test 1: verify get lease work"
19169         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19170
19171         echo "==== test 2: verify lease can be broken by upcoming open"
19172         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19173         local PID=$!
19174         sleep 2
19175
19176         $MULTIOP $DIR/$tfile oO_RDWR:c
19177         kill -USR1 $PID && wait $PID || error "break lease error"
19178
19179         echo "==== test 3: verify lease can't be granted if an open already exists"
19180         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19181         local PID=$!
19182         sleep 2
19183
19184         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19185         kill -USR1 $PID && wait $PID || error "open file error"
19186
19187         echo "==== test 4: lease can sustain over recovery"
19188         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19189         PID=$!
19190         sleep 2
19191
19192         fail mds1
19193
19194         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19195
19196         echo "==== test 5: lease broken can't be regained by replay"
19197         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19198         PID=$!
19199         sleep 2
19200
19201         # open file to break lease and then recovery
19202         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19203         fail mds1
19204
19205         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19206
19207         rm -f $DIR/$tfile
19208 }
19209 run_test 208 "Exclusive open"
19210
19211 test_209() {
19212         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19213                 skip_env "must have disp_stripe"
19214
19215         touch $DIR/$tfile
19216         sync; sleep 5; sync;
19217
19218         echo 3 > /proc/sys/vm/drop_caches
19219         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19220                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19221         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19222
19223         # open/close 500 times
19224         for i in $(seq 500); do
19225                 cat $DIR/$tfile
19226         done
19227
19228         echo 3 > /proc/sys/vm/drop_caches
19229         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19230                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19231         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19232
19233         echo "before: $req_before, after: $req_after"
19234         [ $((req_after - req_before)) -ge 300 ] &&
19235                 error "open/close requests are not freed"
19236         return 0
19237 }
19238 run_test 209 "read-only open/close requests should be freed promptly"
19239
19240 test_210() {
19241         local pid
19242
19243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19244         pid=$!
19245         sleep 1
19246
19247         $LFS getstripe $DIR/$tfile
19248         kill -USR1 $pid
19249         wait $pid || error "multiop failed"
19250
19251         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19252         pid=$!
19253         sleep 1
19254
19255         $LFS getstripe $DIR/$tfile
19256         kill -USR1 $pid
19257         wait $pid || error "multiop failed"
19258 }
19259 run_test 210 "lfs getstripe does not break leases"
19260
19261 test_212() {
19262         size=`date +%s`
19263         size=$((size % 8192 + 1))
19264         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19265         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19266         rm -f $DIR/f212 $DIR/f212.xyz
19267 }
19268 run_test 212 "Sendfile test ============================================"
19269
19270 test_213() {
19271         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19272         cancel_lru_locks osc
19273         lctl set_param fail_loc=0x8000040f
19274         # generate a read lock
19275         cat $DIR/$tfile > /dev/null
19276         # write to the file, it will try to cancel the above read lock.
19277         cat /etc/hosts >> $DIR/$tfile
19278 }
19279 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19280
19281 test_214() { # for bug 20133
19282         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19283         for (( i=0; i < 340; i++ )) ; do
19284                 touch $DIR/$tdir/d214c/a$i
19285         done
19286
19287         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19288         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19289         ls $DIR/d214c || error "ls $DIR/d214c failed"
19290         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19291         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19292 }
19293 run_test 214 "hash-indexed directory test - bug 20133"
19294
19295 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19296 create_lnet_proc_files() {
19297         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19298 }
19299
19300 # counterpart of create_lnet_proc_files
19301 remove_lnet_proc_files() {
19302         rm -f $TMP/lnet_$1.sys
19303 }
19304
19305 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19306 # 3rd arg as regexp for body
19307 check_lnet_proc_stats() {
19308         local l=$(cat "$TMP/lnet_$1" |wc -l)
19309         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19310
19311         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19312 }
19313
19314 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19315 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19316 # optional and can be regexp for 2nd line (lnet.routes case)
19317 check_lnet_proc_entry() {
19318         local blp=2          # blp stands for 'position of 1st line of body'
19319         [ -z "$5" ] || blp=3 # lnet.routes case
19320
19321         local l=$(cat "$TMP/lnet_$1" |wc -l)
19322         # subtracting one from $blp because the body can be empty
19323         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19324
19325         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19326                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19327
19328         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19329                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19330
19331         # bail out if any unexpected line happened
19332         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19333         [ "$?" != 0 ] || error "$2 misformatted"
19334 }
19335
19336 test_215() { # for bugs 18102, 21079, 21517
19337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19338
19339         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19340         local P='[1-9][0-9]*'           # positive numeric
19341         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19342         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19343         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19344         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19345
19346         local L1 # regexp for 1st line
19347         local L2 # regexp for 2nd line (optional)
19348         local BR # regexp for the rest (body)
19349
19350         # lnet.stats should look as 11 space-separated non-negative numerics
19351         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19352         create_lnet_proc_files "stats"
19353         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19354         remove_lnet_proc_files "stats"
19355
19356         # lnet.routes should look like this:
19357         # Routing disabled/enabled
19358         # net hops priority state router
19359         # where net is a string like tcp0, hops > 0, priority >= 0,
19360         # state is up/down,
19361         # router is a string like 192.168.1.1@tcp2
19362         L1="^Routing (disabled|enabled)$"
19363         L2="^net +hops +priority +state +router$"
19364         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19365         create_lnet_proc_files "routes"
19366         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19367         remove_lnet_proc_files "routes"
19368
19369         # lnet.routers should look like this:
19370         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19371         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19372         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19373         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19374         L1="^ref +rtr_ref +alive +router$"
19375         BR="^$P +$P +(up|down) +$NID$"
19376         create_lnet_proc_files "routers"
19377         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19378         remove_lnet_proc_files "routers"
19379
19380         # lnet.peers should look like this:
19381         # nid refs state last max rtr min tx min queue
19382         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19383         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19384         # numeric (0 or >0 or <0), queue >= 0.
19385         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19386         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19387         create_lnet_proc_files "peers"
19388         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19389         remove_lnet_proc_files "peers"
19390
19391         # lnet.buffers  should look like this:
19392         # pages count credits min
19393         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19394         L1="^pages +count +credits +min$"
19395         BR="^ +$N +$N +$I +$I$"
19396         create_lnet_proc_files "buffers"
19397         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19398         remove_lnet_proc_files "buffers"
19399
19400         # lnet.nis should look like this:
19401         # nid status alive refs peer rtr max tx min
19402         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19403         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19404         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19405         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19406         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19407         create_lnet_proc_files "nis"
19408         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19409         remove_lnet_proc_files "nis"
19410
19411         # can we successfully write to lnet.stats?
19412         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19413 }
19414 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19415
19416 test_216() { # bug 20317
19417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19418         remote_ost_nodsh && skip "remote OST with nodsh"
19419
19420         local node
19421         local facets=$(get_facets OST)
19422         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19423
19424         save_lustre_params client "osc.*.contention_seconds" > $p
19425         save_lustre_params $facets \
19426                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19427         save_lustre_params $facets \
19428                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19429         save_lustre_params $facets \
19430                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19431         clear_stats osc.*.osc_stats
19432
19433         # agressive lockless i/o settings
19434         do_nodes $(comma_list $(osts_nodes)) \
19435                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19436                         ldlm.namespaces.filter-*.contended_locks=0 \
19437                         ldlm.namespaces.filter-*.contention_seconds=60"
19438         lctl set_param -n osc.*.contention_seconds=60
19439
19440         $DIRECTIO write $DIR/$tfile 0 10 4096
19441         $CHECKSTAT -s 40960 $DIR/$tfile
19442
19443         # disable lockless i/o
19444         do_nodes $(comma_list $(osts_nodes)) \
19445                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19446                         ldlm.namespaces.filter-*.contended_locks=32 \
19447                         ldlm.namespaces.filter-*.contention_seconds=0"
19448         lctl set_param -n osc.*.contention_seconds=0
19449         clear_stats osc.*.osc_stats
19450
19451         dd if=/dev/zero of=$DIR/$tfile count=0
19452         $CHECKSTAT -s 0 $DIR/$tfile
19453
19454         restore_lustre_params <$p
19455         rm -f $p
19456         rm $DIR/$tfile
19457 }
19458 run_test 216 "check lockless direct write updates file size and kms correctly"
19459
19460 test_217() { # bug 22430
19461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19462
19463         local node
19464         local nid
19465
19466         for node in $(nodes_list); do
19467                 nid=$(host_nids_address $node $NETTYPE)
19468                 if [[ $nid = *-* ]] ; then
19469                         echo "lctl ping $(h2nettype $nid)"
19470                         lctl ping $(h2nettype $nid)
19471                 else
19472                         echo "skipping $node (no hyphen detected)"
19473                 fi
19474         done
19475 }
19476 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19477
19478 test_218() {
19479        # do directio so as not to populate the page cache
19480        log "creating a 10 Mb file"
19481        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19482        log "starting reads"
19483        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19484        log "truncating the file"
19485        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19486        log "killing dd"
19487        kill %+ || true # reads might have finished
19488        echo "wait until dd is finished"
19489        wait
19490        log "removing the temporary file"
19491        rm -rf $DIR/$tfile || error "tmp file removal failed"
19492 }
19493 run_test 218 "parallel read and truncate should not deadlock"
19494
19495 test_219() {
19496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19497
19498         # write one partial page
19499         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19500         # set no grant so vvp_io_commit_write will do sync write
19501         $LCTL set_param fail_loc=0x411
19502         # write a full page at the end of file
19503         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19504
19505         $LCTL set_param fail_loc=0
19506         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19507         $LCTL set_param fail_loc=0x411
19508         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19509
19510         # LU-4201
19511         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19512         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19513 }
19514 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19515
19516 test_220() { #LU-325
19517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19518         remote_ost_nodsh && skip "remote OST with nodsh"
19519         remote_mds_nodsh && skip "remote MDS with nodsh"
19520         remote_mgs_nodsh && skip "remote MGS with nodsh"
19521
19522         local OSTIDX=0
19523
19524         # create on MDT0000 so the last_id and next_id are correct
19525         mkdir_on_mdt0 $DIR/$tdir
19526         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19527         OST=${OST%_UUID}
19528
19529         # on the mdt's osc
19530         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19531         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19532                         osp.$mdtosc_proc1.prealloc_last_id)
19533         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19534                         osp.$mdtosc_proc1.prealloc_next_id)
19535
19536         $LFS df -i
19537
19538         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19539         #define OBD_FAIL_OST_ENOINO              0x229
19540         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19541         create_pool $FSNAME.$TESTNAME || return 1
19542         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19543
19544         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19545
19546         MDSOBJS=$((last_id - next_id))
19547         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19548
19549         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19550         echo "OST still has $count kbytes free"
19551
19552         echo "create $MDSOBJS files @next_id..."
19553         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19554
19555         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19556                         osp.$mdtosc_proc1.prealloc_last_id)
19557         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19558                         osp.$mdtosc_proc1.prealloc_next_id)
19559
19560         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19561         $LFS df -i
19562
19563         echo "cleanup..."
19564
19565         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19566         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19567
19568         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19569                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19570         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19571                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19572         echo "unlink $MDSOBJS files @$next_id..."
19573         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19574 }
19575 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19576
19577 test_221() {
19578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19579
19580         dd if=`which date` of=$MOUNT/date oflag=sync
19581         chmod +x $MOUNT/date
19582
19583         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19584         $LCTL set_param fail_loc=0x80001401
19585
19586         $MOUNT/date > /dev/null
19587         rm -f $MOUNT/date
19588 }
19589 run_test 221 "make sure fault and truncate race to not cause OOM"
19590
19591 test_222a () {
19592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19593
19594         rm -rf $DIR/$tdir
19595         test_mkdir $DIR/$tdir
19596         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19597         createmany -o $DIR/$tdir/$tfile 10
19598         cancel_lru_locks mdc
19599         cancel_lru_locks osc
19600         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19601         $LCTL set_param fail_loc=0x31a
19602         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19603         $LCTL set_param fail_loc=0
19604         rm -r $DIR/$tdir
19605 }
19606 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19607
19608 test_222b () {
19609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19610
19611         rm -rf $DIR/$tdir
19612         test_mkdir $DIR/$tdir
19613         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19614         createmany -o $DIR/$tdir/$tfile 10
19615         cancel_lru_locks mdc
19616         cancel_lru_locks osc
19617         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19618         $LCTL set_param fail_loc=0x31a
19619         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19620         $LCTL set_param fail_loc=0
19621 }
19622 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19623
19624 test_223 () {
19625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19626
19627         rm -rf $DIR/$tdir
19628         test_mkdir $DIR/$tdir
19629         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19630         createmany -o $DIR/$tdir/$tfile 10
19631         cancel_lru_locks mdc
19632         cancel_lru_locks osc
19633         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19634         $LCTL set_param fail_loc=0x31b
19635         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19636         $LCTL set_param fail_loc=0
19637         rm -r $DIR/$tdir
19638 }
19639 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19640
19641 test_224a() { # LU-1039, MRP-303
19642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19643         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19644         $LCTL set_param fail_loc=0x508
19645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19646         $LCTL set_param fail_loc=0
19647         df $DIR
19648 }
19649 run_test 224a "Don't panic on bulk IO failure"
19650
19651 test_224bd_sub() { # LU-1039, MRP-303
19652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19653         local timeout=$1
19654
19655         shift
19656         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19657
19658         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19659
19660         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19661         cancel_lru_locks osc
19662         set_checksums 0
19663         stack_trap "set_checksums $ORIG_CSUM" EXIT
19664         local at_max_saved=0
19665
19666         # adaptive timeouts may prevent seeing the issue
19667         if at_is_enabled; then
19668                 at_max_saved=$(at_max_get mds)
19669                 at_max_set 0 mds client
19670                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19671         fi
19672
19673         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19674         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19675         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19676
19677         do_facet ost1 $LCTL set_param fail_loc=0
19678         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19679         df $DIR
19680 }
19681
19682 test_224b() {
19683         test_224bd_sub 3 error "dd failed"
19684 }
19685 run_test 224b "Don't panic on bulk IO failure"
19686
19687 test_224c() { # LU-6441
19688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19689         remote_mds_nodsh && skip "remote MDS with nodsh"
19690
19691         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19692         save_writethrough $p
19693         set_cache writethrough on
19694
19695         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19696         local at_max=$($LCTL get_param -n at_max)
19697         local timeout=$($LCTL get_param -n timeout)
19698         local test_at="at_max"
19699         local param_at="$FSNAME.sys.at_max"
19700         local test_timeout="timeout"
19701         local param_timeout="$FSNAME.sys.timeout"
19702
19703         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19704
19705         set_persistent_param_and_check client "$test_at" "$param_at" 0
19706         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19707
19708         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19709         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19710         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19711         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19712         sync
19713         do_facet ost1 "$LCTL set_param fail_loc=0"
19714
19715         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19716         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19717                 $timeout
19718
19719         $LCTL set_param -n $pages_per_rpc
19720         restore_lustre_params < $p
19721         rm -f $p
19722 }
19723 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19724
19725 test_224d() { # LU-11169
19726         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19727 }
19728 run_test 224d "Don't corrupt data on bulk IO timeout"
19729
19730 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19731 test_225a () {
19732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19733         if [ -z ${MDSSURVEY} ]; then
19734                 skip_env "mds-survey not found"
19735         fi
19736         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19737                 skip "Need MDS version at least 2.2.51"
19738
19739         local mds=$(facet_host $SINGLEMDS)
19740         local target=$(do_nodes $mds 'lctl dl' |
19741                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19742
19743         local cmd1="file_count=1000 thrhi=4"
19744         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19745         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19746         local cmd="$cmd1 $cmd2 $cmd3"
19747
19748         rm -f ${TMP}/mds_survey*
19749         echo + $cmd
19750         eval $cmd || error "mds-survey with zero-stripe failed"
19751         cat ${TMP}/mds_survey*
19752         rm -f ${TMP}/mds_survey*
19753 }
19754 run_test 225a "Metadata survey sanity with zero-stripe"
19755
19756 test_225b () {
19757         if [ -z ${MDSSURVEY} ]; then
19758                 skip_env "mds-survey not found"
19759         fi
19760         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19761                 skip "Need MDS version at least 2.2.51"
19762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19763         remote_mds_nodsh && skip "remote MDS with nodsh"
19764         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19765                 skip_env "Need to mount OST to test"
19766         fi
19767
19768         local mds=$(facet_host $SINGLEMDS)
19769         local target=$(do_nodes $mds 'lctl dl' |
19770                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19771
19772         local cmd1="file_count=1000 thrhi=4"
19773         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19774         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19775         local cmd="$cmd1 $cmd2 $cmd3"
19776
19777         rm -f ${TMP}/mds_survey*
19778         echo + $cmd
19779         eval $cmd || error "mds-survey with stripe_count failed"
19780         cat ${TMP}/mds_survey*
19781         rm -f ${TMP}/mds_survey*
19782 }
19783 run_test 225b "Metadata survey sanity with stripe_count = 1"
19784
19785 mcreate_path2fid () {
19786         local mode=$1
19787         local major=$2
19788         local minor=$3
19789         local name=$4
19790         local desc=$5
19791         local path=$DIR/$tdir/$name
19792         local fid
19793         local rc
19794         local fid_path
19795
19796         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19797                 error "cannot create $desc"
19798
19799         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19800         rc=$?
19801         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19802
19803         fid_path=$($LFS fid2path $MOUNT $fid)
19804         rc=$?
19805         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19806
19807         [ "$path" == "$fid_path" ] ||
19808                 error "fid2path returned $fid_path, expected $path"
19809
19810         echo "pass with $path and $fid"
19811 }
19812
19813 test_226a () {
19814         rm -rf $DIR/$tdir
19815         mkdir -p $DIR/$tdir
19816
19817         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19818         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19819         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19820         mcreate_path2fid 0040666 0 0 dir "directory"
19821         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19822         mcreate_path2fid 0100666 0 0 file "regular file"
19823         mcreate_path2fid 0120666 0 0 link "symbolic link"
19824         mcreate_path2fid 0140666 0 0 sock "socket"
19825 }
19826 run_test 226a "call path2fid and fid2path on files of all type"
19827
19828 test_226b () {
19829         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19830
19831         local MDTIDX=1
19832
19833         rm -rf $DIR/$tdir
19834         mkdir -p $DIR/$tdir
19835         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19836                 error "create remote directory failed"
19837         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19838         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19839                                 "character special file (null)"
19840         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19841                                 "character special file (no device)"
19842         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19843         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19844                                 "block special file (loop)"
19845         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19846         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19847         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19848 }
19849 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19850
19851 test_226c () {
19852         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19853         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19854                 skip "Need MDS version at least 2.13.55"
19855
19856         local submnt=/mnt/submnt
19857         local srcfile=/etc/passwd
19858         local dstfile=$submnt/passwd
19859         local path
19860         local fid
19861
19862         rm -rf $DIR/$tdir
19863         rm -rf $submnt
19864         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19865                 error "create remote directory failed"
19866         mkdir -p $submnt || error "create $submnt failed"
19867         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19868                 error "mount $submnt failed"
19869         stack_trap "umount $submnt" EXIT
19870
19871         cp $srcfile $dstfile
19872         fid=$($LFS path2fid $dstfile)
19873         path=$($LFS fid2path $submnt "$fid")
19874         [ "$path" = "$dstfile" ] ||
19875                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19876 }
19877 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19878
19879 # LU-1299 Executing or running ldd on a truncated executable does not
19880 # cause an out-of-memory condition.
19881 test_227() {
19882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19883         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19884
19885         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19886         chmod +x $MOUNT/date
19887
19888         $MOUNT/date > /dev/null
19889         ldd $MOUNT/date > /dev/null
19890         rm -f $MOUNT/date
19891 }
19892 run_test 227 "running truncated executable does not cause OOM"
19893
19894 # LU-1512 try to reuse idle OI blocks
19895 test_228a() {
19896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19897         remote_mds_nodsh && skip "remote MDS with nodsh"
19898         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19899
19900         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19901         local myDIR=$DIR/$tdir
19902
19903         mkdir -p $myDIR
19904         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19905         $LCTL set_param fail_loc=0x80001002
19906         createmany -o $myDIR/t- 10000
19907         $LCTL set_param fail_loc=0
19908         # The guard is current the largest FID holder
19909         touch $myDIR/guard
19910         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19911                     tr -d '[')
19912         local IDX=$(($SEQ % 64))
19913
19914         do_facet $SINGLEMDS sync
19915         # Make sure journal flushed.
19916         sleep 6
19917         local blk1=$(do_facet $SINGLEMDS \
19918                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19919                      grep Blockcount | awk '{print $4}')
19920
19921         # Remove old files, some OI blocks will become idle.
19922         unlinkmany $myDIR/t- 10000
19923         # Create new files, idle OI blocks should be reused.
19924         createmany -o $myDIR/t- 2000
19925         do_facet $SINGLEMDS sync
19926         # Make sure journal flushed.
19927         sleep 6
19928         local blk2=$(do_facet $SINGLEMDS \
19929                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19930                      grep Blockcount | awk '{print $4}')
19931
19932         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19933 }
19934 run_test 228a "try to reuse idle OI blocks"
19935
19936 test_228b() {
19937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19938         remote_mds_nodsh && skip "remote MDS with nodsh"
19939         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19940
19941         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19942         local myDIR=$DIR/$tdir
19943
19944         mkdir -p $myDIR
19945         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19946         $LCTL set_param fail_loc=0x80001002
19947         createmany -o $myDIR/t- 10000
19948         $LCTL set_param fail_loc=0
19949         # The guard is current the largest FID holder
19950         touch $myDIR/guard
19951         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19952                     tr -d '[')
19953         local IDX=$(($SEQ % 64))
19954
19955         do_facet $SINGLEMDS sync
19956         # Make sure journal flushed.
19957         sleep 6
19958         local blk1=$(do_facet $SINGLEMDS \
19959                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19960                      grep Blockcount | awk '{print $4}')
19961
19962         # Remove old files, some OI blocks will become idle.
19963         unlinkmany $myDIR/t- 10000
19964
19965         # stop the MDT
19966         stop $SINGLEMDS || error "Fail to stop MDT."
19967         # remount the MDT
19968         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19969                 error "Fail to start MDT."
19970
19971         df $MOUNT || error "Fail to df."
19972         # Create new files, idle OI blocks should be reused.
19973         createmany -o $myDIR/t- 2000
19974         do_facet $SINGLEMDS sync
19975         # Make sure journal flushed.
19976         sleep 6
19977         local blk2=$(do_facet $SINGLEMDS \
19978                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19979                      grep Blockcount | awk '{print $4}')
19980
19981         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19982 }
19983 run_test 228b "idle OI blocks can be reused after MDT restart"
19984
19985 #LU-1881
19986 test_228c() {
19987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19988         remote_mds_nodsh && skip "remote MDS with nodsh"
19989         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19990
19991         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19992         local myDIR=$DIR/$tdir
19993
19994         mkdir -p $myDIR
19995         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19996         $LCTL set_param fail_loc=0x80001002
19997         # 20000 files can guarantee there are index nodes in the OI file
19998         createmany -o $myDIR/t- 20000
19999         $LCTL set_param fail_loc=0
20000         # The guard is current the largest FID holder
20001         touch $myDIR/guard
20002         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20003                     tr -d '[')
20004         local IDX=$(($SEQ % 64))
20005
20006         do_facet $SINGLEMDS sync
20007         # Make sure journal flushed.
20008         sleep 6
20009         local blk1=$(do_facet $SINGLEMDS \
20010                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20011                      grep Blockcount | awk '{print $4}')
20012
20013         # Remove old files, some OI blocks will become idle.
20014         unlinkmany $myDIR/t- 20000
20015         rm -f $myDIR/guard
20016         # The OI file should become empty now
20017
20018         # Create new files, idle OI blocks should be reused.
20019         createmany -o $myDIR/t- 2000
20020         do_facet $SINGLEMDS sync
20021         # Make sure journal flushed.
20022         sleep 6
20023         local blk2=$(do_facet $SINGLEMDS \
20024                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20025                      grep Blockcount | awk '{print $4}')
20026
20027         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20028 }
20029 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20030
20031 test_229() { # LU-2482, LU-3448
20032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20033         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20034         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20035                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20036
20037         rm -f $DIR/$tfile
20038
20039         # Create a file with a released layout and stripe count 2.
20040         $MULTIOP $DIR/$tfile H2c ||
20041                 error "failed to create file with released layout"
20042
20043         $LFS getstripe -v $DIR/$tfile
20044
20045         local pattern=$($LFS getstripe -L $DIR/$tfile)
20046         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20047
20048         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20049                 error "getstripe"
20050         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20051         stat $DIR/$tfile || error "failed to stat released file"
20052
20053         chown $RUNAS_ID $DIR/$tfile ||
20054                 error "chown $RUNAS_ID $DIR/$tfile failed"
20055
20056         chgrp $RUNAS_ID $DIR/$tfile ||
20057                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20058
20059         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20060         rm $DIR/$tfile || error "failed to remove released file"
20061 }
20062 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20063
20064 test_230a() {
20065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20067         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20068                 skip "Need MDS version at least 2.11.52"
20069
20070         local MDTIDX=1
20071
20072         test_mkdir $DIR/$tdir
20073         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20074         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20075         [ $mdt_idx -ne 0 ] &&
20076                 error "create local directory on wrong MDT $mdt_idx"
20077
20078         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20079                         error "create remote directory failed"
20080         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20081         [ $mdt_idx -ne $MDTIDX ] &&
20082                 error "create remote directory on wrong MDT $mdt_idx"
20083
20084         createmany -o $DIR/$tdir/test_230/t- 10 ||
20085                 error "create files on remote directory failed"
20086         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20087         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20088         rm -r $DIR/$tdir || error "unlink remote directory failed"
20089 }
20090 run_test 230a "Create remote directory and files under the remote directory"
20091
20092 test_230b() {
20093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20094         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20095         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20096                 skip "Need MDS version at least 2.11.52"
20097
20098         local MDTIDX=1
20099         local mdt_index
20100         local i
20101         local file
20102         local pid
20103         local stripe_count
20104         local migrate_dir=$DIR/$tdir/migrate_dir
20105         local other_dir=$DIR/$tdir/other_dir
20106
20107         test_mkdir $DIR/$tdir
20108         test_mkdir -i0 -c1 $migrate_dir
20109         test_mkdir -i0 -c1 $other_dir
20110         for ((i=0; i<10; i++)); do
20111                 mkdir -p $migrate_dir/dir_${i}
20112                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20113                         error "create files under remote dir failed $i"
20114         done
20115
20116         cp /etc/passwd $migrate_dir/$tfile
20117         cp /etc/passwd $other_dir/$tfile
20118         chattr +SAD $migrate_dir
20119         chattr +SAD $migrate_dir/$tfile
20120
20121         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20122         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20123         local old_dir_mode=$(stat -c%f $migrate_dir)
20124         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20125
20126         mkdir -p $migrate_dir/dir_default_stripe2
20127         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20128         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20129
20130         mkdir -p $other_dir
20131         ln $migrate_dir/$tfile $other_dir/luna
20132         ln $migrate_dir/$tfile $migrate_dir/sofia
20133         ln $other_dir/$tfile $migrate_dir/david
20134         ln -s $migrate_dir/$tfile $other_dir/zachary
20135         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20136         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20137
20138         local len
20139         local lnktgt
20140
20141         # inline symlink
20142         for len in 58 59 60; do
20143                 lnktgt=$(str_repeat 'l' $len)
20144                 touch $migrate_dir/$lnktgt
20145                 ln -s $lnktgt $migrate_dir/${len}char_ln
20146         done
20147
20148         # PATH_MAX
20149         for len in 4094 4095; do
20150                 lnktgt=$(str_repeat 'l' $len)
20151                 ln -s $lnktgt $migrate_dir/${len}char_ln
20152         done
20153
20154         # NAME_MAX
20155         for len in 254 255; do
20156                 touch $migrate_dir/$(str_repeat 'l' $len)
20157         done
20158
20159         $LFS migrate -m $MDTIDX $migrate_dir ||
20160                 error "fails on migrating remote dir to MDT1"
20161
20162         echo "migratate to MDT1, then checking.."
20163         for ((i = 0; i < 10; i++)); do
20164                 for file in $(find $migrate_dir/dir_${i}); do
20165                         mdt_index=$($LFS getstripe -m $file)
20166                         # broken symlink getstripe will fail
20167                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20168                                 error "$file is not on MDT${MDTIDX}"
20169                 done
20170         done
20171
20172         # the multiple link file should still in MDT0
20173         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20174         [ $mdt_index == 0 ] ||
20175                 error "$file is not on MDT${MDTIDX}"
20176
20177         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20178         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20179                 error " expect $old_dir_flag get $new_dir_flag"
20180
20181         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20182         [ "$old_file_flag" = "$new_file_flag" ] ||
20183                 error " expect $old_file_flag get $new_file_flag"
20184
20185         local new_dir_mode=$(stat -c%f $migrate_dir)
20186         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20187                 error "expect mode $old_dir_mode get $new_dir_mode"
20188
20189         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20190         [ "$old_file_mode" = "$new_file_mode" ] ||
20191                 error "expect mode $old_file_mode get $new_file_mode"
20192
20193         diff /etc/passwd $migrate_dir/$tfile ||
20194                 error "$tfile different after migration"
20195
20196         diff /etc/passwd $other_dir/luna ||
20197                 error "luna different after migration"
20198
20199         diff /etc/passwd $migrate_dir/sofia ||
20200                 error "sofia different after migration"
20201
20202         diff /etc/passwd $migrate_dir/david ||
20203                 error "david different after migration"
20204
20205         diff /etc/passwd $other_dir/zachary ||
20206                 error "zachary different after migration"
20207
20208         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20209                 error "${tfile}_ln different after migration"
20210
20211         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20212                 error "${tfile}_ln_other different after migration"
20213
20214         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20215         [ $stripe_count = 2 ] ||
20216                 error "dir strpe_count $d != 2 after migration."
20217
20218         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20219         [ $stripe_count = 2 ] ||
20220                 error "file strpe_count $d != 2 after migration."
20221
20222         #migrate back to MDT0
20223         MDTIDX=0
20224
20225         $LFS migrate -m $MDTIDX $migrate_dir ||
20226                 error "fails on migrating remote dir to MDT0"
20227
20228         echo "migrate back to MDT0, checking.."
20229         for file in $(find $migrate_dir); do
20230                 mdt_index=$($LFS getstripe -m $file)
20231                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20232                         error "$file is not on MDT${MDTIDX}"
20233         done
20234
20235         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20236         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20237                 error " expect $old_dir_flag get $new_dir_flag"
20238
20239         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20240         [ "$old_file_flag" = "$new_file_flag" ] ||
20241                 error " expect $old_file_flag get $new_file_flag"
20242
20243         local new_dir_mode=$(stat -c%f $migrate_dir)
20244         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20245                 error "expect mode $old_dir_mode get $new_dir_mode"
20246
20247         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20248         [ "$old_file_mode" = "$new_file_mode" ] ||
20249                 error "expect mode $old_file_mode get $new_file_mode"
20250
20251         diff /etc/passwd ${migrate_dir}/$tfile ||
20252                 error "$tfile different after migration"
20253
20254         diff /etc/passwd ${other_dir}/luna ||
20255                 error "luna different after migration"
20256
20257         diff /etc/passwd ${migrate_dir}/sofia ||
20258                 error "sofia different after migration"
20259
20260         diff /etc/passwd ${other_dir}/zachary ||
20261                 error "zachary different after migration"
20262
20263         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20264                 error "${tfile}_ln different after migration"
20265
20266         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20267                 error "${tfile}_ln_other different after migration"
20268
20269         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20270         [ $stripe_count = 2 ] ||
20271                 error "dir strpe_count $d != 2 after migration."
20272
20273         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20274         [ $stripe_count = 2 ] ||
20275                 error "file strpe_count $d != 2 after migration."
20276
20277         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20278 }
20279 run_test 230b "migrate directory"
20280
20281 test_230c() {
20282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20284         remote_mds_nodsh && skip "remote MDS with nodsh"
20285         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20286                 skip "Need MDS version at least 2.11.52"
20287
20288         local MDTIDX=1
20289         local total=3
20290         local mdt_index
20291         local file
20292         local migrate_dir=$DIR/$tdir/migrate_dir
20293
20294         #If migrating directory fails in the middle, all entries of
20295         #the directory is still accessiable.
20296         test_mkdir $DIR/$tdir
20297         test_mkdir -i0 -c1 $migrate_dir
20298         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20299         stat $migrate_dir
20300         createmany -o $migrate_dir/f $total ||
20301                 error "create files under ${migrate_dir} failed"
20302
20303         # fail after migrating top dir, and this will fail only once, so the
20304         # first sub file migration will fail (currently f3), others succeed.
20305         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20306         do_facet mds1 lctl set_param fail_loc=0x1801
20307         local t=$(ls $migrate_dir | wc -l)
20308         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20309                 error "migrate should fail"
20310         local u=$(ls $migrate_dir | wc -l)
20311         [ "$u" == "$t" ] || error "$u != $t during migration"
20312
20313         # add new dir/file should succeed
20314         mkdir $migrate_dir/dir ||
20315                 error "mkdir failed under migrating directory"
20316         touch $migrate_dir/file ||
20317                 error "create file failed under migrating directory"
20318
20319         # add file with existing name should fail
20320         for file in $migrate_dir/f*; do
20321                 stat $file > /dev/null || error "stat $file failed"
20322                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20323                         error "open(O_CREAT|O_EXCL) $file should fail"
20324                 $MULTIOP $file m && error "create $file should fail"
20325                 touch $DIR/$tdir/remote_dir/$tfile ||
20326                         error "touch $tfile failed"
20327                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20328                         error "link $file should fail"
20329                 mdt_index=$($LFS getstripe -m $file)
20330                 if [ $mdt_index == 0 ]; then
20331                         # file failed to migrate is not allowed to rename to
20332                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20333                                 error "rename to $file should fail"
20334                 else
20335                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20336                                 error "rename to $file failed"
20337                 fi
20338                 echo hello >> $file || error "write $file failed"
20339         done
20340
20341         # resume migration with different options should fail
20342         $LFS migrate -m 0 $migrate_dir &&
20343                 error "migrate -m 0 $migrate_dir should fail"
20344
20345         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20346                 error "migrate -c 2 $migrate_dir should fail"
20347
20348         # resume migration should succeed
20349         $LFS migrate -m $MDTIDX $migrate_dir ||
20350                 error "migrate $migrate_dir failed"
20351
20352         echo "Finish migration, then checking.."
20353         for file in $(find $migrate_dir); do
20354                 mdt_index=$($LFS getstripe -m $file)
20355                 [ $mdt_index == $MDTIDX ] ||
20356                         error "$file is not on MDT${MDTIDX}"
20357         done
20358
20359         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20360 }
20361 run_test 230c "check directory accessiblity if migration failed"
20362
20363 test_230d() {
20364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20366         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20367                 skip "Need MDS version at least 2.11.52"
20368         # LU-11235
20369         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20370
20371         local migrate_dir=$DIR/$tdir/migrate_dir
20372         local old_index
20373         local new_index
20374         local old_count
20375         local new_count
20376         local new_hash
20377         local mdt_index
20378         local i
20379         local j
20380
20381         old_index=$((RANDOM % MDSCOUNT))
20382         old_count=$((MDSCOUNT - old_index))
20383         new_index=$((RANDOM % MDSCOUNT))
20384         new_count=$((MDSCOUNT - new_index))
20385         new_hash=1 # for all_char
20386
20387         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20388         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20389
20390         test_mkdir $DIR/$tdir
20391         test_mkdir -i $old_index -c $old_count $migrate_dir
20392
20393         for ((i=0; i<100; i++)); do
20394                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20395                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20396                         error "create files under remote dir failed $i"
20397         done
20398
20399         echo -n "Migrate from MDT$old_index "
20400         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20401         echo -n "to MDT$new_index"
20402         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20403         echo
20404
20405         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20406         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20407                 error "migrate remote dir error"
20408
20409         echo "Finish migration, then checking.."
20410         for file in $(find $migrate_dir -maxdepth 1); do
20411                 mdt_index=$($LFS getstripe -m $file)
20412                 if [ $mdt_index -lt $new_index ] ||
20413                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20414                         error "$file is on MDT$mdt_index"
20415                 fi
20416         done
20417
20418         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20419 }
20420 run_test 230d "check migrate big directory"
20421
20422 test_230e() {
20423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20424         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20425         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20426                 skip "Need MDS version at least 2.11.52"
20427
20428         local i
20429         local j
20430         local a_fid
20431         local b_fid
20432
20433         mkdir_on_mdt0 $DIR/$tdir
20434         mkdir $DIR/$tdir/migrate_dir
20435         mkdir $DIR/$tdir/other_dir
20436         touch $DIR/$tdir/migrate_dir/a
20437         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20438         ls $DIR/$tdir/other_dir
20439
20440         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20441                 error "migrate dir fails"
20442
20443         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20444         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20445
20446         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20447         [ $mdt_index == 0 ] || error "a is not on MDT0"
20448
20449         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20450                 error "migrate dir fails"
20451
20452         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20453         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20454
20455         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20456         [ $mdt_index == 1 ] || error "a is not on MDT1"
20457
20458         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20459         [ $mdt_index == 1 ] || error "b is not on MDT1"
20460
20461         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20462         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20463
20464         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20465
20466         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20467 }
20468 run_test 230e "migrate mulitple local link files"
20469
20470 test_230f() {
20471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20474                 skip "Need MDS version at least 2.11.52"
20475
20476         local a_fid
20477         local ln_fid
20478
20479         mkdir -p $DIR/$tdir
20480         mkdir $DIR/$tdir/migrate_dir
20481         $LFS mkdir -i1 $DIR/$tdir/other_dir
20482         touch $DIR/$tdir/migrate_dir/a
20483         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20484         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20485         ls $DIR/$tdir/other_dir
20486
20487         # a should be migrated to MDT1, since no other links on MDT0
20488         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20489                 error "#1 migrate dir fails"
20490         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20491         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20492         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20493         [ $mdt_index == 1 ] || error "a is not on MDT1"
20494
20495         # a should stay on MDT1, because it is a mulitple link file
20496         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20497                 error "#2 migrate dir fails"
20498         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20499         [ $mdt_index == 1 ] || error "a is not on MDT1"
20500
20501         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20502                 error "#3 migrate dir fails"
20503
20504         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20505         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20506         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20507
20508         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20509         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20510
20511         # a should be migrated to MDT0, since no other links on MDT1
20512         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20513                 error "#4 migrate dir fails"
20514         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20515         [ $mdt_index == 0 ] || error "a is not on MDT0"
20516
20517         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20518 }
20519 run_test 230f "migrate mulitple remote link files"
20520
20521 test_230g() {
20522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20524         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20525                 skip "Need MDS version at least 2.11.52"
20526
20527         mkdir -p $DIR/$tdir/migrate_dir
20528
20529         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20530                 error "migrating dir to non-exist MDT succeeds"
20531         true
20532 }
20533 run_test 230g "migrate dir to non-exist MDT"
20534
20535 test_230h() {
20536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20537         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20538         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20539                 skip "Need MDS version at least 2.11.52"
20540
20541         local mdt_index
20542
20543         mkdir -p $DIR/$tdir/migrate_dir
20544
20545         $LFS migrate -m1 $DIR &&
20546                 error "migrating mountpoint1 should fail"
20547
20548         $LFS migrate -m1 $DIR/$tdir/.. &&
20549                 error "migrating mountpoint2 should fail"
20550
20551         # same as mv
20552         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20553                 error "migrating $tdir/migrate_dir/.. should fail"
20554
20555         true
20556 }
20557 run_test 230h "migrate .. and root"
20558
20559 test_230i() {
20560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20561         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20562         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20563                 skip "Need MDS version at least 2.11.52"
20564
20565         mkdir -p $DIR/$tdir/migrate_dir
20566
20567         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20568                 error "migration fails with a tailing slash"
20569
20570         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20571                 error "migration fails with two tailing slashes"
20572 }
20573 run_test 230i "lfs migrate -m tolerates trailing slashes"
20574
20575 test_230j() {
20576         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20577         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20578                 skip "Need MDS version at least 2.11.52"
20579
20580         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20581         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20582                 error "create $tfile failed"
20583         cat /etc/passwd > $DIR/$tdir/$tfile
20584
20585         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20586
20587         cmp /etc/passwd $DIR/$tdir/$tfile ||
20588                 error "DoM file mismatch after migration"
20589 }
20590 run_test 230j "DoM file data not changed after dir migration"
20591
20592 test_230k() {
20593         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20594         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20595                 skip "Need MDS version at least 2.11.56"
20596
20597         local total=20
20598         local files_on_starting_mdt=0
20599
20600         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20601         $LFS getdirstripe $DIR/$tdir
20602         for i in $(seq $total); do
20603                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20604                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20605                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20606         done
20607
20608         echo "$files_on_starting_mdt files on MDT0"
20609
20610         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20611         $LFS getdirstripe $DIR/$tdir
20612
20613         files_on_starting_mdt=0
20614         for i in $(seq $total); do
20615                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20616                         error "file $tfile.$i mismatch after migration"
20617                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20618                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20619         done
20620
20621         echo "$files_on_starting_mdt files on MDT1 after migration"
20622         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20623
20624         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20625         $LFS getdirstripe $DIR/$tdir
20626
20627         files_on_starting_mdt=0
20628         for i in $(seq $total); do
20629                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20630                         error "file $tfile.$i mismatch after 2nd migration"
20631                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20632                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20633         done
20634
20635         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20636         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20637
20638         true
20639 }
20640 run_test 230k "file data not changed after dir migration"
20641
20642 test_230l() {
20643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20644         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20645                 skip "Need MDS version at least 2.11.56"
20646
20647         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20648         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20649                 error "create files under remote dir failed $i"
20650         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20651 }
20652 run_test 230l "readdir between MDTs won't crash"
20653
20654 test_230m() {
20655         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20656         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20657                 skip "Need MDS version at least 2.11.56"
20658
20659         local MDTIDX=1
20660         local mig_dir=$DIR/$tdir/migrate_dir
20661         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20662         local shortstr="b"
20663         local val
20664
20665         echo "Creating files and dirs with xattrs"
20666         test_mkdir $DIR/$tdir
20667         test_mkdir -i0 -c1 $mig_dir
20668         mkdir $mig_dir/dir
20669         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20670                 error "cannot set xattr attr1 on dir"
20671         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20672                 error "cannot set xattr attr2 on dir"
20673         touch $mig_dir/dir/f0
20674         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20675                 error "cannot set xattr attr1 on file"
20676         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20677                 error "cannot set xattr attr2 on file"
20678         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20679         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20680         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20681         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20682         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20683         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20684         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20685         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20686         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20687
20688         echo "Migrating to MDT1"
20689         $LFS migrate -m $MDTIDX $mig_dir ||
20690                 error "fails on migrating dir to MDT1"
20691
20692         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20693         echo "Checking xattrs"
20694         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20695         [ "$val" = $longstr ] ||
20696                 error "expecting xattr1 $longstr on dir, found $val"
20697         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20698         [ "$val" = $shortstr ] ||
20699                 error "expecting xattr2 $shortstr on dir, found $val"
20700         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20701         [ "$val" = $longstr ] ||
20702                 error "expecting xattr1 $longstr on file, found $val"
20703         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20704         [ "$val" = $shortstr ] ||
20705                 error "expecting xattr2 $shortstr on file, found $val"
20706 }
20707 run_test 230m "xattrs not changed after dir migration"
20708
20709 test_230n() {
20710         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20711         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20712                 skip "Need MDS version at least 2.13.53"
20713
20714         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20715         cat /etc/hosts > $DIR/$tdir/$tfile
20716         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20717         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20718
20719         cmp /etc/hosts $DIR/$tdir/$tfile ||
20720                 error "File data mismatch after migration"
20721 }
20722 run_test 230n "Dir migration with mirrored file"
20723
20724 test_230o() {
20725         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20726         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20727                 skip "Need MDS version at least 2.13.52"
20728
20729         local mdts=$(comma_list $(mdts_nodes))
20730         local timeout=100
20731         local restripe_status
20732         local delta
20733         local i
20734
20735         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20736
20737         # in case "crush" hash type is not set
20738         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20739
20740         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20741                            mdt.*MDT0000.enable_dir_restripe)
20742         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20743         stack_trap "do_nodes $mdts $LCTL set_param \
20744                     mdt.*.enable_dir_restripe=$restripe_status"
20745
20746         mkdir $DIR/$tdir
20747         createmany -m $DIR/$tdir/f 100 ||
20748                 error "create files under remote dir failed $i"
20749         createmany -d $DIR/$tdir/d 100 ||
20750                 error "create dirs under remote dir failed $i"
20751
20752         for i in $(seq 2 $MDSCOUNT); do
20753                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20754                 $LFS setdirstripe -c $i $DIR/$tdir ||
20755                         error "split -c $i $tdir failed"
20756                 wait_update $HOSTNAME \
20757                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20758                         error "dir split not finished"
20759                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20760                         awk '/migrate/ {sum += $2} END { print sum }')
20761                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20762                 # delta is around total_files/stripe_count
20763                 (( $delta < 200 / (i - 1) + 4 )) ||
20764                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20765         done
20766 }
20767 run_test 230o "dir split"
20768
20769 test_230p() {
20770         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20771         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20772                 skip "Need MDS version at least 2.13.52"
20773
20774         local mdts=$(comma_list $(mdts_nodes))
20775         local timeout=100
20776         local restripe_status
20777         local delta
20778         local c
20779
20780         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20781
20782         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20783
20784         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20785                            mdt.*MDT0000.enable_dir_restripe)
20786         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20787         stack_trap "do_nodes $mdts $LCTL set_param \
20788                     mdt.*.enable_dir_restripe=$restripe_status"
20789
20790         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20791         createmany -m $DIR/$tdir/f 100 ||
20792                 error "create files under remote dir failed"
20793         createmany -d $DIR/$tdir/d 100 ||
20794                 error "create dirs under remote dir failed"
20795
20796         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20797                 local mdt_hash="crush"
20798
20799                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20800                 $LFS setdirstripe -c $c $DIR/$tdir ||
20801                         error "split -c $c $tdir failed"
20802                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20803                         mdt_hash="$mdt_hash,fixed"
20804                 elif [ $c -eq 1 ]; then
20805                         mdt_hash="none"
20806                 fi
20807                 wait_update $HOSTNAME \
20808                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20809                         error "dir merge not finished"
20810                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20811                         awk '/migrate/ {sum += $2} END { print sum }')
20812                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20813                 # delta is around total_files/stripe_count
20814                 (( delta < 200 / c + 4 )) ||
20815                         error "$delta files migrated >= $((200 / c + 4))"
20816         done
20817 }
20818 run_test 230p "dir merge"
20819
20820 test_230q() {
20821         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20822         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20823                 skip "Need MDS version at least 2.13.52"
20824
20825         local mdts=$(comma_list $(mdts_nodes))
20826         local saved_threshold=$(do_facet mds1 \
20827                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20828         local saved_delta=$(do_facet mds1 \
20829                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20830         local threshold=100
20831         local delta=2
20832         local total=0
20833         local stripe_count=0
20834         local stripe_index
20835         local nr_files
20836         local create
20837
20838         # test with fewer files on ZFS
20839         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20840
20841         stack_trap "do_nodes $mdts $LCTL set_param \
20842                     mdt.*.dir_split_count=$saved_threshold"
20843         stack_trap "do_nodes $mdts $LCTL set_param \
20844                     mdt.*.dir_split_delta=$saved_delta"
20845         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20846         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20847         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20848         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20849         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20850         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20851
20852         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20853         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20854
20855         create=$((threshold * 3 / 2))
20856         while [ $stripe_count -lt $MDSCOUNT ]; do
20857                 createmany -m $DIR/$tdir/f $total $create ||
20858                         error "create sub files failed"
20859                 stat $DIR/$tdir > /dev/null
20860                 total=$((total + create))
20861                 stripe_count=$((stripe_count + delta))
20862                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20863
20864                 wait_update $HOSTNAME \
20865                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20866                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20867
20868                 wait_update $HOSTNAME \
20869                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20870                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20871
20872                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20873                 echo "$nr_files/$total files on MDT$stripe_index after split"
20874                 # allow 10% margin of imbalance with crush hash
20875                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20876                         error "$nr_files files on MDT$stripe_index after split"
20877
20878                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20879                 [ $nr_files -eq $total ] ||
20880                         error "total sub files $nr_files != $total"
20881         done
20882
20883         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20884
20885         echo "fixed layout directory won't auto split"
20886         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20887         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20888                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20889         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20890                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20891 }
20892 run_test 230q "dir auto split"
20893
20894 test_230r() {
20895         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20896         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20897         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20898                 skip "Need MDS version at least 2.13.54"
20899
20900         # maximum amount of local locks:
20901         # parent striped dir - 2 locks
20902         # new stripe in parent to migrate to - 1 lock
20903         # source and target - 2 locks
20904         # Total 5 locks for regular file
20905         mkdir -p $DIR/$tdir
20906         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20907         touch $DIR/$tdir/dir1/eee
20908
20909         # create 4 hardlink for 4 more locks
20910         # Total: 9 locks > RS_MAX_LOCKS (8)
20911         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20912         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20913         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20914         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20915         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20916         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20917         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20918         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20919
20920         cancel_lru_locks mdc
20921
20922         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20923                 error "migrate dir fails"
20924
20925         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20926 }
20927 run_test 230r "migrate with too many local locks"
20928
20929 test_230s() {
20930         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20931                 skip "Need MDS version at least 2.14.52"
20932
20933         local mdts=$(comma_list $(mdts_nodes))
20934         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20935                                 mdt.*MDT0000.enable_dir_restripe)
20936
20937         stack_trap "do_nodes $mdts $LCTL set_param \
20938                     mdt.*.enable_dir_restripe=$restripe_status"
20939
20940         local st
20941         for st in 0 1; do
20942                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20943                 test_mkdir $DIR/$tdir
20944                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20945                         error "$LFS mkdir should return EEXIST if target exists"
20946                 rmdir $DIR/$tdir
20947         done
20948 }
20949 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20950
20951 test_230t()
20952 {
20953         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20954         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20955                 skip "Need MDS version at least 2.14.50"
20956
20957         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20958         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20959         $LFS project -p 1 -s $DIR/$tdir ||
20960                 error "set $tdir project id failed"
20961         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20962                 error "set subdir project id failed"
20963         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20964 }
20965 run_test 230t "migrate directory with project ID set"
20966
20967 test_230u()
20968 {
20969         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20970         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20971                 skip "Need MDS version at least 2.14.53"
20972
20973         local count
20974
20975         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20976         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20977         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20978         for i in $(seq 0 $((MDSCOUNT - 1))); do
20979                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20980                 echo "$count dirs migrated to MDT$i"
20981         done
20982         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20983         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20984 }
20985 run_test 230u "migrate directory by QOS"
20986
20987 test_230v()
20988 {
20989         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20990         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20991                 skip "Need MDS version at least 2.14.53"
20992
20993         local count
20994
20995         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20996         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20997         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20998         for i in $(seq 0 $((MDSCOUNT - 1))); do
20999                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21000                 echo "$count subdirs migrated to MDT$i"
21001                 (( i == 3 )) && (( count > 0 )) &&
21002                         error "subdir shouldn't be migrated to MDT3"
21003         done
21004         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21005         (( count == 3 )) || error "dirs migrated to $count MDTs"
21006 }
21007 run_test 230v "subdir migrated to the MDT where its parent is located"
21008
21009 test_230w() {
21010         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21011         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21012                 skip "Need MDS version at least 2.15.0"
21013
21014         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21015         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21016         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21017
21018         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21019                 error "migrate failed"
21020
21021         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21022                 error "$tdir stripe count mismatch"
21023
21024         for i in $(seq 0 9); do
21025                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21026                         error "d$i is striped"
21027         done
21028 }
21029 run_test 230w "non-recursive mode dir migration"
21030
21031 test_230x() {
21032         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21033         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21034                 skip "Need MDS version at least 2.15.0"
21035
21036         mkdir -p $DIR/$tdir || error "mkdir failed"
21037         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21038
21039         local mdt_name=$(mdtname_from_index 0)
21040         local low=$(do_facet mds2 $LCTL get_param -n \
21041                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21042         local high=$(do_facet mds2 $LCTL get_param -n \
21043                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21044         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21045         local maxage=$(do_facet mds2 $LCTL get_param -n \
21046                 osp.*$mdt_name-osp-MDT0001.maxage)
21047
21048         stack_trap "do_facet mds2 $LCTL set_param -n \
21049                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21050                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21051         stack_trap "do_facet mds2 $LCTL set_param -n \
21052                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21053
21054         do_facet mds2 $LCTL set_param -n \
21055                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21056         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21057         sleep 4
21058         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21059                 error "migrate $tdir should fail"
21060
21061         do_facet mds2 $LCTL set_param -n \
21062                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21063         do_facet mds2 $LCTL set_param -n \
21064                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21065         sleep 4
21066         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21067                 error "migrate failed"
21068         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21069                 error "$tdir stripe count mismatch"
21070 }
21071 run_test 230x "dir migration check space"
21072
21073 test_231a()
21074 {
21075         # For simplicity this test assumes that max_pages_per_rpc
21076         # is the same across all OSCs
21077         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21078         local bulk_size=$((max_pages * PAGE_SIZE))
21079         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21080                                        head -n 1)
21081
21082         mkdir -p $DIR/$tdir
21083         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21084                 error "failed to set stripe with -S ${brw_size}M option"
21085
21086         # clear the OSC stats
21087         $LCTL set_param osc.*.stats=0 &>/dev/null
21088         stop_writeback
21089
21090         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21091         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21092                 oflag=direct &>/dev/null || error "dd failed"
21093
21094         sync; sleep 1; sync # just to be safe
21095         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21096         if [ x$nrpcs != "x1" ]; then
21097                 $LCTL get_param osc.*.stats
21098                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21099         fi
21100
21101         start_writeback
21102         # Drop the OSC cache, otherwise we will read from it
21103         cancel_lru_locks osc
21104
21105         # clear the OSC stats
21106         $LCTL set_param osc.*.stats=0 &>/dev/null
21107
21108         # Client reads $bulk_size.
21109         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21110                 iflag=direct &>/dev/null || error "dd failed"
21111
21112         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21113         if [ x$nrpcs != "x1" ]; then
21114                 $LCTL get_param osc.*.stats
21115                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21116         fi
21117 }
21118 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21119
21120 test_231b() {
21121         mkdir -p $DIR/$tdir
21122         local i
21123         for i in {0..1023}; do
21124                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21125                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21126                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21127         done
21128         sync
21129 }
21130 run_test 231b "must not assert on fully utilized OST request buffer"
21131
21132 test_232a() {
21133         mkdir -p $DIR/$tdir
21134         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21135
21136         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21137         do_facet ost1 $LCTL set_param fail_loc=0x31c
21138
21139         # ignore dd failure
21140         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21141
21142         do_facet ost1 $LCTL set_param fail_loc=0
21143         umount_client $MOUNT || error "umount failed"
21144         mount_client $MOUNT || error "mount failed"
21145         stop ost1 || error "cannot stop ost1"
21146         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21147 }
21148 run_test 232a "failed lock should not block umount"
21149
21150 test_232b() {
21151         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21152                 skip "Need MDS version at least 2.10.58"
21153
21154         mkdir -p $DIR/$tdir
21155         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21156         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21157         sync
21158         cancel_lru_locks osc
21159
21160         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21161         do_facet ost1 $LCTL set_param fail_loc=0x31c
21162
21163         # ignore failure
21164         $LFS data_version $DIR/$tdir/$tfile || true
21165
21166         do_facet ost1 $LCTL set_param fail_loc=0
21167         umount_client $MOUNT || error "umount failed"
21168         mount_client $MOUNT || error "mount failed"
21169         stop ost1 || error "cannot stop ost1"
21170         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21171 }
21172 run_test 232b "failed data version lock should not block umount"
21173
21174 test_233a() {
21175         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21176                 skip "Need MDS version at least 2.3.64"
21177         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21178
21179         local fid=$($LFS path2fid $MOUNT)
21180
21181         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21182                 error "cannot access $MOUNT using its FID '$fid'"
21183 }
21184 run_test 233a "checking that OBF of the FS root succeeds"
21185
21186 test_233b() {
21187         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21188                 skip "Need MDS version at least 2.5.90"
21189         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21190
21191         local fid=$($LFS path2fid $MOUNT/.lustre)
21192
21193         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21194                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21195
21196         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21197         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21198                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21199 }
21200 run_test 233b "checking that OBF of the FS .lustre succeeds"
21201
21202 test_234() {
21203         local p="$TMP/sanityN-$TESTNAME.parameters"
21204         save_lustre_params client "llite.*.xattr_cache" > $p
21205         lctl set_param llite.*.xattr_cache 1 ||
21206                 skip_env "xattr cache is not supported"
21207
21208         mkdir -p $DIR/$tdir || error "mkdir failed"
21209         touch $DIR/$tdir/$tfile || error "touch failed"
21210         # OBD_FAIL_LLITE_XATTR_ENOMEM
21211         $LCTL set_param fail_loc=0x1405
21212         getfattr -n user.attr $DIR/$tdir/$tfile &&
21213                 error "getfattr should have failed with ENOMEM"
21214         $LCTL set_param fail_loc=0x0
21215         rm -rf $DIR/$tdir
21216
21217         restore_lustre_params < $p
21218         rm -f $p
21219 }
21220 run_test 234 "xattr cache should not crash on ENOMEM"
21221
21222 test_235() {
21223         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21224                 skip "Need MDS version at least 2.4.52"
21225
21226         flock_deadlock $DIR/$tfile
21227         local RC=$?
21228         case $RC in
21229                 0)
21230                 ;;
21231                 124) error "process hangs on a deadlock"
21232                 ;;
21233                 *) error "error executing flock_deadlock $DIR/$tfile"
21234                 ;;
21235         esac
21236 }
21237 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21238
21239 #LU-2935
21240 test_236() {
21241         check_swap_layouts_support
21242
21243         local ref1=/etc/passwd
21244         local ref2=/etc/group
21245         local file1=$DIR/$tdir/f1
21246         local file2=$DIR/$tdir/f2
21247
21248         test_mkdir -c1 $DIR/$tdir
21249         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21250         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21251         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21252         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21253         local fd=$(free_fd)
21254         local cmd="exec $fd<>$file2"
21255         eval $cmd
21256         rm $file2
21257         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21258                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21259         cmd="exec $fd>&-"
21260         eval $cmd
21261         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21262
21263         #cleanup
21264         rm -rf $DIR/$tdir
21265 }
21266 run_test 236 "Layout swap on open unlinked file"
21267
21268 # LU-4659 linkea consistency
21269 test_238() {
21270         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21271                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21272                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21273                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21274
21275         touch $DIR/$tfile
21276         ln $DIR/$tfile $DIR/$tfile.lnk
21277         touch $DIR/$tfile.new
21278         mv $DIR/$tfile.new $DIR/$tfile
21279         local fid1=$($LFS path2fid $DIR/$tfile)
21280         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21281         local path1=$($LFS fid2path $FSNAME "$fid1")
21282         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21283         local path2=$($LFS fid2path $FSNAME "$fid2")
21284         [ $tfile.lnk == $path2 ] ||
21285                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21286         rm -f $DIR/$tfile*
21287 }
21288 run_test 238 "Verify linkea consistency"
21289
21290 test_239A() { # was test_239
21291         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21292                 skip "Need MDS version at least 2.5.60"
21293
21294         local list=$(comma_list $(mdts_nodes))
21295
21296         mkdir -p $DIR/$tdir
21297         createmany -o $DIR/$tdir/f- 5000
21298         unlinkmany $DIR/$tdir/f- 5000
21299         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21300                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21301         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21302                         osp.*MDT*.sync_in_flight" | calc_sum)
21303         [ "$changes" -eq 0 ] || error "$changes not synced"
21304 }
21305 run_test 239A "osp_sync test"
21306
21307 test_239a() { #LU-5297
21308         remote_mds_nodsh && skip "remote MDS with nodsh"
21309
21310         touch $DIR/$tfile
21311         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21312         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21313         chgrp $RUNAS_GID $DIR/$tfile
21314         wait_delete_completed
21315 }
21316 run_test 239a "process invalid osp sync record correctly"
21317
21318 test_239b() { #LU-5297
21319         remote_mds_nodsh && skip "remote MDS with nodsh"
21320
21321         touch $DIR/$tfile1
21322         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21323         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21324         chgrp $RUNAS_GID $DIR/$tfile1
21325         wait_delete_completed
21326         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21327         touch $DIR/$tfile2
21328         chgrp $RUNAS_GID $DIR/$tfile2
21329         wait_delete_completed
21330 }
21331 run_test 239b "process osp sync record with ENOMEM error correctly"
21332
21333 test_240() {
21334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21335         remote_mds_nodsh && skip "remote MDS with nodsh"
21336
21337         mkdir -p $DIR/$tdir
21338
21339         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21340                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21341         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21342                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21343
21344         umount_client $MOUNT || error "umount failed"
21345         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21346         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21347         mount_client $MOUNT || error "failed to mount client"
21348
21349         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21350         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21351 }
21352 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21353
21354 test_241_bio() {
21355         local count=$1
21356         local bsize=$2
21357
21358         for LOOP in $(seq $count); do
21359                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21360                 cancel_lru_locks $OSC || true
21361         done
21362 }
21363
21364 test_241_dio() {
21365         local count=$1
21366         local bsize=$2
21367
21368         for LOOP in $(seq $1); do
21369                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21370                         2>/dev/null
21371         done
21372 }
21373
21374 test_241a() { # was test_241
21375         local bsize=$PAGE_SIZE
21376
21377         (( bsize < 40960 )) && bsize=40960
21378         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21379         ls -la $DIR/$tfile
21380         cancel_lru_locks $OSC
21381         test_241_bio 1000 $bsize &
21382         PID=$!
21383         test_241_dio 1000 $bsize
21384         wait $PID
21385 }
21386 run_test 241a "bio vs dio"
21387
21388 test_241b() {
21389         local bsize=$PAGE_SIZE
21390
21391         (( bsize < 40960 )) && bsize=40960
21392         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21393         ls -la $DIR/$tfile
21394         test_241_dio 1000 $bsize &
21395         PID=$!
21396         test_241_dio 1000 $bsize
21397         wait $PID
21398 }
21399 run_test 241b "dio vs dio"
21400
21401 test_242() {
21402         remote_mds_nodsh && skip "remote MDS with nodsh"
21403
21404         mkdir_on_mdt0 $DIR/$tdir
21405         touch $DIR/$tdir/$tfile
21406
21407         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21408         do_facet mds1 lctl set_param fail_loc=0x105
21409         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21410
21411         do_facet mds1 lctl set_param fail_loc=0
21412         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21413 }
21414 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21415
21416 test_243()
21417 {
21418         test_mkdir $DIR/$tdir
21419         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21420 }
21421 run_test 243 "various group lock tests"
21422
21423 test_244a()
21424 {
21425         test_mkdir $DIR/$tdir
21426         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21427         sendfile_grouplock $DIR/$tdir/$tfile || \
21428                 error "sendfile+grouplock failed"
21429         rm -rf $DIR/$tdir
21430 }
21431 run_test 244a "sendfile with group lock tests"
21432
21433 test_244b()
21434 {
21435         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21436
21437         local threads=50
21438         local size=$((1024*1024))
21439
21440         test_mkdir $DIR/$tdir
21441         for i in $(seq 1 $threads); do
21442                 local file=$DIR/$tdir/file_$((i / 10))
21443                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21444                 local pids[$i]=$!
21445         done
21446         for i in $(seq 1 $threads); do
21447                 wait ${pids[$i]}
21448         done
21449 }
21450 run_test 244b "multi-threaded write with group lock"
21451
21452 test_245a() {
21453         local flagname="multi_mod_rpcs"
21454         local connect_data_name="max_mod_rpcs"
21455         local out
21456
21457         # check if multiple modify RPCs flag is set
21458         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21459                 grep "connect_flags:")
21460         echo "$out"
21461
21462         echo "$out" | grep -qw $flagname
21463         if [ $? -ne 0 ]; then
21464                 echo "connect flag $flagname is not set"
21465                 return
21466         fi
21467
21468         # check if multiple modify RPCs data is set
21469         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21470         echo "$out"
21471
21472         echo "$out" | grep -qw $connect_data_name ||
21473                 error "import should have connect data $connect_data_name"
21474 }
21475 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21476
21477 test_245b() {
21478         local flagname="multi_mod_rpcs"
21479         local connect_data_name="max_mod_rpcs"
21480         local out
21481
21482         remote_mds_nodsh && skip "remote MDS with nodsh"
21483         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21484
21485         # check if multiple modify RPCs flag is set
21486         out=$(do_facet mds1 \
21487               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21488               grep "connect_flags:")
21489         echo "$out"
21490
21491         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21492
21493         # check if multiple modify RPCs data is set
21494         out=$(do_facet mds1 \
21495               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21496
21497         [[ "$out" =~ $connect_data_name ]] ||
21498                 {
21499                         echo "$out"
21500                         error "missing connect data $connect_data_name"
21501                 }
21502 }
21503 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21504
21505 cleanup_247() {
21506         local submount=$1
21507
21508         trap 0
21509         umount_client $submount
21510         rmdir $submount
21511 }
21512
21513 test_247a() {
21514         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21515                 grep -q subtree ||
21516                 skip_env "Fileset feature is not supported"
21517
21518         local submount=${MOUNT}_$tdir
21519
21520         mkdir $MOUNT/$tdir
21521         mkdir -p $submount || error "mkdir $submount failed"
21522         FILESET="$FILESET/$tdir" mount_client $submount ||
21523                 error "mount $submount failed"
21524         trap "cleanup_247 $submount" EXIT
21525         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21526         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21527                 error "read $MOUNT/$tdir/$tfile failed"
21528         cleanup_247 $submount
21529 }
21530 run_test 247a "mount subdir as fileset"
21531
21532 test_247b() {
21533         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21534                 skip_env "Fileset feature is not supported"
21535
21536         local submount=${MOUNT}_$tdir
21537
21538         rm -rf $MOUNT/$tdir
21539         mkdir -p $submount || error "mkdir $submount failed"
21540         SKIP_FILESET=1
21541         FILESET="$FILESET/$tdir" mount_client $submount &&
21542                 error "mount $submount should fail"
21543         rmdir $submount
21544 }
21545 run_test 247b "mount subdir that dose not exist"
21546
21547 test_247c() {
21548         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21549                 skip_env "Fileset feature is not supported"
21550
21551         local submount=${MOUNT}_$tdir
21552
21553         mkdir -p $MOUNT/$tdir/dir1
21554         mkdir -p $submount || error "mkdir $submount failed"
21555         trap "cleanup_247 $submount" EXIT
21556         FILESET="$FILESET/$tdir" mount_client $submount ||
21557                 error "mount $submount failed"
21558         local fid=$($LFS path2fid $MOUNT/)
21559         $LFS fid2path $submount $fid && error "fid2path should fail"
21560         cleanup_247 $submount
21561 }
21562 run_test 247c "running fid2path outside subdirectory root"
21563
21564 test_247d() {
21565         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21566                 skip "Fileset feature is not supported"
21567
21568         local submount=${MOUNT}_$tdir
21569
21570         mkdir -p $MOUNT/$tdir/dir1
21571         mkdir -p $submount || error "mkdir $submount failed"
21572         FILESET="$FILESET/$tdir" mount_client $submount ||
21573                 error "mount $submount failed"
21574         trap "cleanup_247 $submount" EXIT
21575
21576         local td=$submount/dir1
21577         local fid=$($LFS path2fid $td)
21578         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21579
21580         # check that we get the same pathname back
21581         local rootpath
21582         local found
21583         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21584                 echo "$rootpath $fid"
21585                 found=$($LFS fid2path $rootpath "$fid")
21586                 [ -n "$found" ] || error "fid2path should succeed"
21587                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21588         done
21589         # check wrong root path format
21590         rootpath=$submount"_wrong"
21591         found=$($LFS fid2path $rootpath "$fid")
21592         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21593
21594         cleanup_247 $submount
21595 }
21596 run_test 247d "running fid2path inside subdirectory root"
21597
21598 # LU-8037
21599 test_247e() {
21600         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21601                 grep -q subtree ||
21602                 skip "Fileset feature is not supported"
21603
21604         local submount=${MOUNT}_$tdir
21605
21606         mkdir $MOUNT/$tdir
21607         mkdir -p $submount || error "mkdir $submount failed"
21608         FILESET="$FILESET/.." mount_client $submount &&
21609                 error "mount $submount should fail"
21610         rmdir $submount
21611 }
21612 run_test 247e "mount .. as fileset"
21613
21614 test_247f() {
21615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21616         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21617                 skip "Need at least version 2.13.52"
21618         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21619                 skip "Need at least version 2.14.50"
21620         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21621                 grep -q subtree ||
21622                 skip "Fileset feature is not supported"
21623
21624         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21625         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21626                 error "mkdir remote failed"
21627         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21628                 error "mkdir remote/subdir failed"
21629         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21630                 error "mkdir striped failed"
21631         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21632
21633         local submount=${MOUNT}_$tdir
21634
21635         mkdir -p $submount || error "mkdir $submount failed"
21636         stack_trap "rmdir $submount"
21637
21638         local dir
21639         local stat
21640         local fileset=$FILESET
21641         local mdts=$(comma_list $(mdts_nodes))
21642
21643         stat=$(do_facet mds1 $LCTL get_param -n \
21644                 mdt.*MDT0000.enable_remote_subdir_mount)
21645         stack_trap "do_nodes $mdts $LCTL set_param \
21646                 mdt.*.enable_remote_subdir_mount=$stat"
21647
21648         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21649         stack_trap "umount_client $submount"
21650         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21651                 error "mount remote dir $dir should fail"
21652
21653         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21654                 $tdir/striped/. ; do
21655                 FILESET="$fileset/$dir" mount_client $submount ||
21656                         error "mount $dir failed"
21657                 umount_client $submount
21658         done
21659
21660         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21661         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21662                 error "mount $tdir/remote failed"
21663 }
21664 run_test 247f "mount striped or remote directory as fileset"
21665
21666 test_247g() {
21667         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21668         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21669                 skip "Need at least version 2.14.50"
21670
21671         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21672                 error "mkdir $tdir failed"
21673         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21674
21675         local submount=${MOUNT}_$tdir
21676
21677         mkdir -p $submount || error "mkdir $submount failed"
21678         stack_trap "rmdir $submount"
21679
21680         FILESET="$fileset/$tdir" mount_client $submount ||
21681                 error "mount $dir failed"
21682         stack_trap "umount $submount"
21683
21684         local mdts=$(comma_list $(mdts_nodes))
21685
21686         local nrpcs
21687
21688         stat $submount > /dev/null
21689         cancel_lru_locks $MDC
21690         stat $submount > /dev/null
21691         stat $submount/$tfile > /dev/null
21692         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21693         stat $submount/$tfile > /dev/null
21694         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21695                 awk '/getattr/ {sum += $2} END {print sum}')
21696
21697         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21698 }
21699 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21700
21701 test_248a() {
21702         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21703         [ -z "$fast_read_sav" ] && skip "no fast read support"
21704
21705         # create a large file for fast read verification
21706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21707
21708         # make sure the file is created correctly
21709         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21710                 { rm -f $DIR/$tfile; skip "file creation error"; }
21711
21712         echo "Test 1: verify that fast read is 4 times faster on cache read"
21713
21714         # small read with fast read enabled
21715         $LCTL set_param -n llite.*.fast_read=1
21716         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21717                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21718                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21719         # small read with fast read disabled
21720         $LCTL set_param -n llite.*.fast_read=0
21721         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21722                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21723                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21724
21725         # verify that fast read is 4 times faster for cache read
21726         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21727                 error_not_in_vm "fast read was not 4 times faster: " \
21728                            "$t_fast vs $t_slow"
21729
21730         echo "Test 2: verify the performance between big and small read"
21731         $LCTL set_param -n llite.*.fast_read=1
21732
21733         # 1k non-cache read
21734         cancel_lru_locks osc
21735         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21736                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21737                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21738
21739         # 1M non-cache read
21740         cancel_lru_locks osc
21741         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21742                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21743                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21744
21745         # verify that big IO is not 4 times faster than small IO
21746         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21747                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21748
21749         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21750         rm -f $DIR/$tfile
21751 }
21752 run_test 248a "fast read verification"
21753
21754 test_248b() {
21755         # Default short_io_bytes=16384, try both smaller and larger sizes.
21756         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21757         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21758         echo "bs=53248 count=113 normal buffered write"
21759         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21760                 error "dd of initial data file failed"
21761         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21762
21763         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21764         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21765                 error "dd with sync normal writes failed"
21766         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21767
21768         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21769         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21770                 error "dd with sync small writes failed"
21771         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21772
21773         cancel_lru_locks osc
21774
21775         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21776         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21777         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21778         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21779                 iflag=direct || error "dd with O_DIRECT small read failed"
21780         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21781         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21782                 error "compare $TMP/$tfile.1 failed"
21783
21784         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21785         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21786
21787         # just to see what the maximum tunable value is, and test parsing
21788         echo "test invalid parameter 2MB"
21789         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21790                 error "too-large short_io_bytes allowed"
21791         echo "test maximum parameter 512KB"
21792         # if we can set a larger short_io_bytes, run test regardless of version
21793         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21794                 # older clients may not allow setting it this large, that's OK
21795                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21796                         skip "Need at least client version 2.13.50"
21797                 error "medium short_io_bytes failed"
21798         fi
21799         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21800         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21801
21802         echo "test large parameter 64KB"
21803         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21804         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21805
21806         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21807         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21808                 error "dd with sync large writes failed"
21809         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21810
21811         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21812         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21813         num=$((113 * 4096 / PAGE_SIZE))
21814         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21815         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21816                 error "dd with O_DIRECT large writes failed"
21817         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21818                 error "compare $DIR/$tfile.3 failed"
21819
21820         cancel_lru_locks osc
21821
21822         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21823         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21824                 error "dd with O_DIRECT large read failed"
21825         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21826                 error "compare $TMP/$tfile.2 failed"
21827
21828         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21829         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21830                 error "dd with O_DIRECT large read failed"
21831         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21832                 error "compare $TMP/$tfile.3 failed"
21833 }
21834 run_test 248b "test short_io read and write for both small and large sizes"
21835
21836 test_249() { # LU-7890
21837         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21838                 skip "Need at least version 2.8.54"
21839
21840         rm -f $DIR/$tfile
21841         $LFS setstripe -c 1 $DIR/$tfile
21842         # Offset 2T == 4k * 512M
21843         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21844                 error "dd to 2T offset failed"
21845 }
21846 run_test 249 "Write above 2T file size"
21847
21848 test_250() {
21849         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21850          && skip "no 16TB file size limit on ZFS"
21851
21852         $LFS setstripe -c 1 $DIR/$tfile
21853         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21854         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21855         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21856         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21857                 conv=notrunc,fsync && error "append succeeded"
21858         return 0
21859 }
21860 run_test 250 "Write above 16T limit"
21861
21862 test_251() {
21863         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21864
21865         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21866         #Skip once - writing the first stripe will succeed
21867         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21868         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21869                 error "short write happened"
21870
21871         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21872         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21873                 error "short read happened"
21874
21875         rm -f $DIR/$tfile
21876 }
21877 run_test 251 "Handling short read and write correctly"
21878
21879 test_252() {
21880         remote_mds_nodsh && skip "remote MDS with nodsh"
21881         remote_ost_nodsh && skip "remote OST with nodsh"
21882         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21883                 skip_env "ldiskfs only test"
21884         fi
21885
21886         local tgt
21887         local dev
21888         local out
21889         local uuid
21890         local num
21891         local gen
21892
21893         # check lr_reader on OST0000
21894         tgt=ost1
21895         dev=$(facet_device $tgt)
21896         out=$(do_facet $tgt $LR_READER $dev)
21897         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21898         echo "$out"
21899         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21900         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21901                 error "Invalid uuid returned by $LR_READER on target $tgt"
21902         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21903
21904         # check lr_reader -c on MDT0000
21905         tgt=mds1
21906         dev=$(facet_device $tgt)
21907         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21908                 skip "$LR_READER does not support additional options"
21909         fi
21910         out=$(do_facet $tgt $LR_READER -c $dev)
21911         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21912         echo "$out"
21913         num=$(echo "$out" | grep -c "mdtlov")
21914         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21915                 error "Invalid number of mdtlov clients returned by $LR_READER"
21916         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21917
21918         # check lr_reader -cr on MDT0000
21919         out=$(do_facet $tgt $LR_READER -cr $dev)
21920         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21921         echo "$out"
21922         echo "$out" | grep -q "^reply_data:$" ||
21923                 error "$LR_READER should have returned 'reply_data' section"
21924         num=$(echo "$out" | grep -c "client_generation")
21925         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21926 }
21927 run_test 252 "check lr_reader tool"
21928
21929 test_253() {
21930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21931         remote_mds_nodsh && skip "remote MDS with nodsh"
21932         remote_mgs_nodsh && skip "remote MGS with nodsh"
21933
21934         local ostidx=0
21935         local rc=0
21936         local ost_name=$(ostname_from_index $ostidx)
21937
21938         # on the mdt's osc
21939         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21940         do_facet $SINGLEMDS $LCTL get_param -n \
21941                 osp.$mdtosc_proc1.reserved_mb_high ||
21942                 skip  "remote MDS does not support reserved_mb_high"
21943
21944         rm -rf $DIR/$tdir
21945         wait_mds_ost_sync
21946         wait_delete_completed
21947         mkdir $DIR/$tdir
21948
21949         pool_add $TESTNAME || error "Pool creation failed"
21950         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21951
21952         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21953                 error "Setstripe failed"
21954
21955         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21956
21957         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21958                     grep "watermarks")
21959         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21960
21961         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21962                         osp.$mdtosc_proc1.prealloc_status)
21963         echo "prealloc_status $oa_status"
21964
21965         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21966                 error "File creation should fail"
21967
21968         #object allocation was stopped, but we still able to append files
21969         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21970                 oflag=append || error "Append failed"
21971
21972         rm -f $DIR/$tdir/$tfile.0
21973
21974         # For this test, we want to delete the files we created to go out of
21975         # space but leave the watermark, so we remain nearly out of space
21976         ost_watermarks_enospc_delete_files $tfile $ostidx
21977
21978         wait_delete_completed
21979
21980         sleep_maxage
21981
21982         for i in $(seq 10 12); do
21983                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21984                         2>/dev/null || error "File creation failed after rm"
21985         done
21986
21987         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21988                         osp.$mdtosc_proc1.prealloc_status)
21989         echo "prealloc_status $oa_status"
21990
21991         if (( oa_status != 0 )); then
21992                 error "Object allocation still disable after rm"
21993         fi
21994 }
21995 run_test 253 "Check object allocation limit"
21996
21997 test_254() {
21998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21999         remote_mds_nodsh && skip "remote MDS with nodsh"
22000
22001         local mdt=$(facet_svc $SINGLEMDS)
22002
22003         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22004                 skip "MDS does not support changelog_size"
22005
22006         local cl_user
22007
22008         changelog_register || error "changelog_register failed"
22009
22010         changelog_clear 0 || error "changelog_clear failed"
22011
22012         local size1=$(do_facet $SINGLEMDS \
22013                       $LCTL get_param -n mdd.$mdt.changelog_size)
22014         echo "Changelog size $size1"
22015
22016         rm -rf $DIR/$tdir
22017         $LFS mkdir -i 0 $DIR/$tdir
22018         # change something
22019         mkdir -p $DIR/$tdir/pics/2008/zachy
22020         touch $DIR/$tdir/pics/2008/zachy/timestamp
22021         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22022         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22023         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22024         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22025         rm $DIR/$tdir/pics/desktop.jpg
22026
22027         local size2=$(do_facet $SINGLEMDS \
22028                       $LCTL get_param -n mdd.$mdt.changelog_size)
22029         echo "Changelog size after work $size2"
22030
22031         (( $size2 > $size1 )) ||
22032                 error "new Changelog size=$size2 less than old size=$size1"
22033 }
22034 run_test 254 "Check changelog size"
22035
22036 ladvise_no_type()
22037 {
22038         local type=$1
22039         local file=$2
22040
22041         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22042                 awk -F: '{print $2}' | grep $type > /dev/null
22043         if [ $? -ne 0 ]; then
22044                 return 0
22045         fi
22046         return 1
22047 }
22048
22049 ladvise_no_ioctl()
22050 {
22051         local file=$1
22052
22053         lfs ladvise -a willread $file > /dev/null 2>&1
22054         if [ $? -eq 0 ]; then
22055                 return 1
22056         fi
22057
22058         lfs ladvise -a willread $file 2>&1 |
22059                 grep "Inappropriate ioctl for device" > /dev/null
22060         if [ $? -eq 0 ]; then
22061                 return 0
22062         fi
22063         return 1
22064 }
22065
22066 percent() {
22067         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22068 }
22069
22070 # run a random read IO workload
22071 # usage: random_read_iops <filename> <filesize> <iosize>
22072 random_read_iops() {
22073         local file=$1
22074         local fsize=$2
22075         local iosize=${3:-4096}
22076
22077         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22078                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22079 }
22080
22081 drop_file_oss_cache() {
22082         local file="$1"
22083         local nodes="$2"
22084
22085         $LFS ladvise -a dontneed $file 2>/dev/null ||
22086                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22087 }
22088
22089 ladvise_willread_performance()
22090 {
22091         local repeat=10
22092         local average_origin=0
22093         local average_cache=0
22094         local average_ladvise=0
22095
22096         for ((i = 1; i <= $repeat; i++)); do
22097                 echo "Iter $i/$repeat: reading without willread hint"
22098                 cancel_lru_locks osc
22099                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22100                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22101                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22102                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22103
22104                 cancel_lru_locks osc
22105                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22106                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22107                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22108
22109                 cancel_lru_locks osc
22110                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22111                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22112                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22113                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22114                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22115         done
22116         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22117         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22118         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22119
22120         speedup_cache=$(percent $average_cache $average_origin)
22121         speedup_ladvise=$(percent $average_ladvise $average_origin)
22122
22123         echo "Average uncached read: $average_origin"
22124         echo "Average speedup with OSS cached read: " \
22125                 "$average_cache = +$speedup_cache%"
22126         echo "Average speedup with ladvise willread: " \
22127                 "$average_ladvise = +$speedup_ladvise%"
22128
22129         local lowest_speedup=20
22130         if (( ${average_cache%.*} < $lowest_speedup )); then
22131                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22132                      " got $average_cache%. Skipping ladvise willread check."
22133                 return 0
22134         fi
22135
22136         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22137         # it is still good to run until then to exercise 'ladvise willread'
22138         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22139                 [ "$ost1_FSTYPE" = "zfs" ] &&
22140                 echo "osd-zfs does not support dontneed or drop_caches" &&
22141                 return 0
22142
22143         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22144         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22145                 error_not_in_vm "Speedup with willread is less than " \
22146                         "$lowest_speedup%, got $average_ladvise%"
22147 }
22148
22149 test_255a() {
22150         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22151                 skip "lustre < 2.8.54 does not support ladvise "
22152         remote_ost_nodsh && skip "remote OST with nodsh"
22153
22154         stack_trap "rm -f $DIR/$tfile"
22155         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22156
22157         ladvise_no_type willread $DIR/$tfile &&
22158                 skip "willread ladvise is not supported"
22159
22160         ladvise_no_ioctl $DIR/$tfile &&
22161                 skip "ladvise ioctl is not supported"
22162
22163         local size_mb=100
22164         local size=$((size_mb * 1048576))
22165         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22166                 error "dd to $DIR/$tfile failed"
22167
22168         lfs ladvise -a willread $DIR/$tfile ||
22169                 error "Ladvise failed with no range argument"
22170
22171         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22172                 error "Ladvise failed with no -l or -e argument"
22173
22174         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22175                 error "Ladvise failed with only -e argument"
22176
22177         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22178                 error "Ladvise failed with only -l argument"
22179
22180         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22181                 error "End offset should not be smaller than start offset"
22182
22183         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22184                 error "End offset should not be equal to start offset"
22185
22186         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22187                 error "Ladvise failed with overflowing -s argument"
22188
22189         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22190                 error "Ladvise failed with overflowing -e argument"
22191
22192         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22193                 error "Ladvise failed with overflowing -l argument"
22194
22195         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22196                 error "Ladvise succeeded with conflicting -l and -e arguments"
22197
22198         echo "Synchronous ladvise should wait"
22199         local delay=4
22200 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22201         do_nodes $(comma_list $(osts_nodes)) \
22202                 $LCTL set_param fail_val=$delay fail_loc=0x237
22203
22204         local start_ts=$SECONDS
22205         lfs ladvise -a willread $DIR/$tfile ||
22206                 error "Ladvise failed with no range argument"
22207         local end_ts=$SECONDS
22208         local inteval_ts=$((end_ts - start_ts))
22209
22210         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22211                 error "Synchronous advice didn't wait reply"
22212         fi
22213
22214         echo "Asynchronous ladvise shouldn't wait"
22215         local start_ts=$SECONDS
22216         lfs ladvise -a willread -b $DIR/$tfile ||
22217                 error "Ladvise failed with no range argument"
22218         local end_ts=$SECONDS
22219         local inteval_ts=$((end_ts - start_ts))
22220
22221         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22222                 error "Asynchronous advice blocked"
22223         fi
22224
22225         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22226         ladvise_willread_performance
22227 }
22228 run_test 255a "check 'lfs ladvise -a willread'"
22229
22230 facet_meminfo() {
22231         local facet=$1
22232         local info=$2
22233
22234         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22235 }
22236
22237 test_255b() {
22238         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22239                 skip "lustre < 2.8.54 does not support ladvise "
22240         remote_ost_nodsh && skip "remote OST with nodsh"
22241
22242         stack_trap "rm -f $DIR/$tfile"
22243         lfs setstripe -c 1 -i 0 $DIR/$tfile
22244
22245         ladvise_no_type dontneed $DIR/$tfile &&
22246                 skip "dontneed ladvise is not supported"
22247
22248         ladvise_no_ioctl $DIR/$tfile &&
22249                 skip "ladvise ioctl is not supported"
22250
22251         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22252                 [ "$ost1_FSTYPE" = "zfs" ] &&
22253                 skip "zfs-osd does not support 'ladvise dontneed'"
22254
22255         local size_mb=100
22256         local size=$((size_mb * 1048576))
22257         # In order to prevent disturbance of other processes, only check 3/4
22258         # of the memory usage
22259         local kibibytes=$((size_mb * 1024 * 3 / 4))
22260
22261         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22262                 error "dd to $DIR/$tfile failed"
22263
22264         #force write to complete before dropping OST cache & checking memory
22265         sync
22266
22267         local total=$(facet_meminfo ost1 MemTotal)
22268         echo "Total memory: $total KiB"
22269
22270         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22271         local before_read=$(facet_meminfo ost1 Cached)
22272         echo "Cache used before read: $before_read KiB"
22273
22274         lfs ladvise -a willread $DIR/$tfile ||
22275                 error "Ladvise willread failed"
22276         local after_read=$(facet_meminfo ost1 Cached)
22277         echo "Cache used after read: $after_read KiB"
22278
22279         lfs ladvise -a dontneed $DIR/$tfile ||
22280                 error "Ladvise dontneed again failed"
22281         local no_read=$(facet_meminfo ost1 Cached)
22282         echo "Cache used after dontneed ladvise: $no_read KiB"
22283
22284         if [ $total -lt $((before_read + kibibytes)) ]; then
22285                 echo "Memory is too small, abort checking"
22286                 return 0
22287         fi
22288
22289         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22290                 error "Ladvise willread should use more memory" \
22291                         "than $kibibytes KiB"
22292         fi
22293
22294         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22295                 error "Ladvise dontneed should release more memory" \
22296                         "than $kibibytes KiB"
22297         fi
22298 }
22299 run_test 255b "check 'lfs ladvise -a dontneed'"
22300
22301 test_255c() {
22302         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22303                 skip "lustre < 2.10.50 does not support lockahead"
22304
22305         local ost1_imp=$(get_osc_import_name client ost1)
22306         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22307                          cut -d'.' -f2)
22308         local count
22309         local new_count
22310         local difference
22311         local i
22312         local rc
22313
22314         test_mkdir -p $DIR/$tdir
22315         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22316
22317         #test 10 returns only success/failure
22318         i=10
22319         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22320         rc=$?
22321         if [ $rc -eq 255 ]; then
22322                 error "Ladvise test${i} failed, ${rc}"
22323         fi
22324
22325         #test 11 counts lock enqueue requests, all others count new locks
22326         i=11
22327         count=$(do_facet ost1 \
22328                 $LCTL get_param -n ost.OSS.ost.stats)
22329         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22330
22331         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22332         rc=$?
22333         if [ $rc -eq 255 ]; then
22334                 error "Ladvise test${i} failed, ${rc}"
22335         fi
22336
22337         new_count=$(do_facet ost1 \
22338                 $LCTL get_param -n ost.OSS.ost.stats)
22339         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22340                    awk '{ print $2 }')
22341
22342         difference="$((new_count - count))"
22343         if [ $difference -ne $rc ]; then
22344                 error "Ladvise test${i}, bad enqueue count, returned " \
22345                       "${rc}, actual ${difference}"
22346         fi
22347
22348         for i in $(seq 12 21); do
22349                 # If we do not do this, we run the risk of having too many
22350                 # locks and starting lock cancellation while we are checking
22351                 # lock counts.
22352                 cancel_lru_locks osc
22353
22354                 count=$($LCTL get_param -n \
22355                        ldlm.namespaces.$imp_name.lock_unused_count)
22356
22357                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22358                 rc=$?
22359                 if [ $rc -eq 255 ]; then
22360                         error "Ladvise test ${i} failed, ${rc}"
22361                 fi
22362
22363                 new_count=$($LCTL get_param -n \
22364                        ldlm.namespaces.$imp_name.lock_unused_count)
22365                 difference="$((new_count - count))"
22366
22367                 # Test 15 output is divided by 100 to map down to valid return
22368                 if [ $i -eq 15 ]; then
22369                         rc="$((rc * 100))"
22370                 fi
22371
22372                 if [ $difference -ne $rc ]; then
22373                         error "Ladvise test ${i}, bad lock count, returned " \
22374                               "${rc}, actual ${difference}"
22375                 fi
22376         done
22377
22378         #test 22 returns only success/failure
22379         i=22
22380         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22381         rc=$?
22382         if [ $rc -eq 255 ]; then
22383                 error "Ladvise test${i} failed, ${rc}"
22384         fi
22385 }
22386 run_test 255c "suite of ladvise lockahead tests"
22387
22388 test_256() {
22389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22390         remote_mds_nodsh && skip "remote MDS with nodsh"
22391         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22392         changelog_users $SINGLEMDS | grep "^cl" &&
22393                 skip "active changelog user"
22394
22395         local cl_user
22396         local cat_sl
22397         local mdt_dev
22398
22399         mdt_dev=$(facet_device $SINGLEMDS)
22400         echo $mdt_dev
22401
22402         changelog_register || error "changelog_register failed"
22403
22404         rm -rf $DIR/$tdir
22405         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22406
22407         changelog_clear 0 || error "changelog_clear failed"
22408
22409         # change something
22410         touch $DIR/$tdir/{1..10}
22411
22412         # stop the MDT
22413         stop $SINGLEMDS || error "Fail to stop MDT"
22414
22415         # remount the MDT
22416         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22417                 error "Fail to start MDT"
22418
22419         #after mount new plainllog is used
22420         touch $DIR/$tdir/{11..19}
22421         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22422         stack_trap "rm -f $tmpfile"
22423         cat_sl=$(do_facet $SINGLEMDS "sync; \
22424                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22425                  llog_reader $tmpfile | grep -c type=1064553b")
22426         do_facet $SINGLEMDS llog_reader $tmpfile
22427
22428         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22429
22430         changelog_clear 0 || error "changelog_clear failed"
22431
22432         cat_sl=$(do_facet $SINGLEMDS "sync; \
22433                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22434                  llog_reader $tmpfile | grep -c type=1064553b")
22435
22436         if (( cat_sl == 2 )); then
22437                 error "Empty plain llog was not deleted from changelog catalog"
22438         elif (( cat_sl != 1 )); then
22439                 error "Active plain llog shouldn't be deleted from catalog"
22440         fi
22441 }
22442 run_test 256 "Check llog delete for empty and not full state"
22443
22444 test_257() {
22445         remote_mds_nodsh && skip "remote MDS with nodsh"
22446         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22447                 skip "Need MDS version at least 2.8.55"
22448
22449         test_mkdir $DIR/$tdir
22450
22451         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22452                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22453         stat $DIR/$tdir
22454
22455 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22456         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22457         local facet=mds$((mdtidx + 1))
22458         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22459         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22460
22461         stop $facet || error "stop MDS failed"
22462         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22463                 error "start MDS fail"
22464         wait_recovery_complete $facet
22465 }
22466 run_test 257 "xattr locks are not lost"
22467
22468 # Verify we take the i_mutex when security requires it
22469 test_258a() {
22470 #define OBD_FAIL_IMUTEX_SEC 0x141c
22471         $LCTL set_param fail_loc=0x141c
22472         touch $DIR/$tfile
22473         chmod u+s $DIR/$tfile
22474         chmod a+rwx $DIR/$tfile
22475         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22476         RC=$?
22477         if [ $RC -ne 0 ]; then
22478                 error "error, failed to take i_mutex, rc=$?"
22479         fi
22480         rm -f $DIR/$tfile
22481 }
22482 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22483
22484 # Verify we do NOT take the i_mutex in the normal case
22485 test_258b() {
22486 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22487         $LCTL set_param fail_loc=0x141d
22488         touch $DIR/$tfile
22489         chmod a+rwx $DIR
22490         chmod a+rw $DIR/$tfile
22491         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22492         RC=$?
22493         if [ $RC -ne 0 ]; then
22494                 error "error, took i_mutex unnecessarily, rc=$?"
22495         fi
22496         rm -f $DIR/$tfile
22497
22498 }
22499 run_test 258b "verify i_mutex security behavior"
22500
22501 test_259() {
22502         local file=$DIR/$tfile
22503         local before
22504         local after
22505
22506         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22507
22508         stack_trap "rm -f $file" EXIT
22509
22510         wait_delete_completed
22511         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22512         echo "before: $before"
22513
22514         $LFS setstripe -i 0 -c 1 $file
22515         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22516         sync_all_data
22517         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22518         echo "after write: $after"
22519
22520 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22521         do_facet ost1 $LCTL set_param fail_loc=0x2301
22522         $TRUNCATE $file 0
22523         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22524         echo "after truncate: $after"
22525
22526         stop ost1
22527         do_facet ost1 $LCTL set_param fail_loc=0
22528         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22529         sleep 2
22530         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22531         echo "after restart: $after"
22532         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22533                 error "missing truncate?"
22534
22535         return 0
22536 }
22537 run_test 259 "crash at delayed truncate"
22538
22539 test_260() {
22540 #define OBD_FAIL_MDC_CLOSE               0x806
22541         $LCTL set_param fail_loc=0x80000806
22542         touch $DIR/$tfile
22543
22544 }
22545 run_test 260 "Check mdc_close fail"
22546
22547 ### Data-on-MDT sanity tests ###
22548 test_270a() {
22549         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22550                 skip "Need MDS version at least 2.10.55 for DoM"
22551
22552         # create DoM file
22553         local dom=$DIR/$tdir/dom_file
22554         local tmp=$DIR/$tdir/tmp_file
22555
22556         mkdir_on_mdt0 $DIR/$tdir
22557
22558         # basic checks for DoM component creation
22559         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22560                 error "Can set MDT layout to non-first entry"
22561
22562         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22563                 error "Can define multiple entries as MDT layout"
22564
22565         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22566
22567         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22568         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22569         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22570
22571         local mdtidx=$($LFS getstripe -m $dom)
22572         local mdtname=MDT$(printf %04x $mdtidx)
22573         local facet=mds$((mdtidx + 1))
22574         local space_check=1
22575
22576         # Skip free space checks with ZFS
22577         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22578
22579         # write
22580         sync
22581         local size_tmp=$((65536 * 3))
22582         local mdtfree1=$(do_facet $facet \
22583                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22584
22585         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22586         # check also direct IO along write
22587         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22588         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22589         sync
22590         cmp $tmp $dom || error "file data is different"
22591         [ $(stat -c%s $dom) == $size_tmp ] ||
22592                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22593         if [ $space_check == 1 ]; then
22594                 local mdtfree2=$(do_facet $facet \
22595                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22596
22597                 # increase in usage from by $size_tmp
22598                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22599                         error "MDT free space wrong after write: " \
22600                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22601         fi
22602
22603         # truncate
22604         local size_dom=10000
22605
22606         $TRUNCATE $dom $size_dom
22607         [ $(stat -c%s $dom) == $size_dom ] ||
22608                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22609         if [ $space_check == 1 ]; then
22610                 mdtfree1=$(do_facet $facet \
22611                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22612                 # decrease in usage from $size_tmp to new $size_dom
22613                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22614                   $(((size_tmp - size_dom) / 1024)) ] ||
22615                         error "MDT free space is wrong after truncate: " \
22616                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22617         fi
22618
22619         # append
22620         cat $tmp >> $dom
22621         sync
22622         size_dom=$((size_dom + size_tmp))
22623         [ $(stat -c%s $dom) == $size_dom ] ||
22624                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22625         if [ $space_check == 1 ]; then
22626                 mdtfree2=$(do_facet $facet \
22627                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22628                 # increase in usage by $size_tmp from previous
22629                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22630                         error "MDT free space is wrong after append: " \
22631                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22632         fi
22633
22634         # delete
22635         rm $dom
22636         if [ $space_check == 1 ]; then
22637                 mdtfree1=$(do_facet $facet \
22638                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22639                 # decrease in usage by $size_dom from previous
22640                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22641                         error "MDT free space is wrong after removal: " \
22642                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22643         fi
22644
22645         # combined striping
22646         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22647                 error "Can't create DoM + OST striping"
22648
22649         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22650         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22651         # check also direct IO along write
22652         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22653         sync
22654         cmp $tmp $dom || error "file data is different"
22655         [ $(stat -c%s $dom) == $size_tmp ] ||
22656                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22657         rm $dom $tmp
22658
22659         return 0
22660 }
22661 run_test 270a "DoM: basic functionality tests"
22662
22663 test_270b() {
22664         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22665                 skip "Need MDS version at least 2.10.55"
22666
22667         local dom=$DIR/$tdir/dom_file
22668         local max_size=1048576
22669
22670         mkdir -p $DIR/$tdir
22671         $LFS setstripe -E $max_size -L mdt $dom
22672
22673         # truncate over the limit
22674         $TRUNCATE $dom $(($max_size + 1)) &&
22675                 error "successful truncate over the maximum size"
22676         # write over the limit
22677         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22678                 error "successful write over the maximum size"
22679         # append over the limit
22680         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22681         echo "12345" >> $dom && error "successful append over the maximum size"
22682         rm $dom
22683
22684         return 0
22685 }
22686 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22687
22688 test_270c() {
22689         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22690                 skip "Need MDS version at least 2.10.55"
22691
22692         mkdir -p $DIR/$tdir
22693         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22694
22695         # check files inherit DoM EA
22696         touch $DIR/$tdir/first
22697         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22698                 error "bad pattern"
22699         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22700                 error "bad stripe count"
22701         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22702                 error "bad stripe size"
22703
22704         # check directory inherits DoM EA and uses it as default
22705         mkdir $DIR/$tdir/subdir
22706         touch $DIR/$tdir/subdir/second
22707         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22708                 error "bad pattern in sub-directory"
22709         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22710                 error "bad stripe count in sub-directory"
22711         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22712                 error "bad stripe size in sub-directory"
22713         return 0
22714 }
22715 run_test 270c "DoM: DoM EA inheritance tests"
22716
22717 test_270d() {
22718         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22719                 skip "Need MDS version at least 2.10.55"
22720
22721         mkdir -p $DIR/$tdir
22722         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22723
22724         # inherit default DoM striping
22725         mkdir $DIR/$tdir/subdir
22726         touch $DIR/$tdir/subdir/f1
22727
22728         # change default directory striping
22729         $LFS setstripe -c 1 $DIR/$tdir/subdir
22730         touch $DIR/$tdir/subdir/f2
22731         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22732                 error "wrong default striping in file 2"
22733         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22734                 error "bad pattern in file 2"
22735         return 0
22736 }
22737 run_test 270d "DoM: change striping from DoM to RAID0"
22738
22739 test_270e() {
22740         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22741                 skip "Need MDS version at least 2.10.55"
22742
22743         mkdir -p $DIR/$tdir/dom
22744         mkdir -p $DIR/$tdir/norm
22745         DOMFILES=20
22746         NORMFILES=10
22747         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22748         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22749
22750         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22751         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22752
22753         # find DoM files by layout
22754         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22755         [ $NUM -eq  $DOMFILES ] ||
22756                 error "lfs find -L: found $NUM, expected $DOMFILES"
22757         echo "Test 1: lfs find 20 DOM files by layout: OK"
22758
22759         # there should be 1 dir with default DOM striping
22760         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22761         [ $NUM -eq  1 ] ||
22762                 error "lfs find -L: found $NUM, expected 1 dir"
22763         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22764
22765         # find DoM files by stripe size
22766         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22767         [ $NUM -eq  $DOMFILES ] ||
22768                 error "lfs find -S: found $NUM, expected $DOMFILES"
22769         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22770
22771         # find files by stripe offset except DoM files
22772         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22773         [ $NUM -eq  $NORMFILES ] ||
22774                 error "lfs find -i: found $NUM, expected $NORMFILES"
22775         echo "Test 5: lfs find no DOM files by stripe index: OK"
22776         return 0
22777 }
22778 run_test 270e "DoM: lfs find with DoM files test"
22779
22780 test_270f() {
22781         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22782                 skip "Need MDS version at least 2.10.55"
22783
22784         local mdtname=${FSNAME}-MDT0000-mdtlov
22785         local dom=$DIR/$tdir/dom_file
22786         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22787                                                 lod.$mdtname.dom_stripesize)
22788         local dom_limit=131072
22789
22790         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22791         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22792                                                 lod.$mdtname.dom_stripesize)
22793         [ ${dom_limit} -eq ${dom_current} ] ||
22794                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22795
22796         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22797         $LFS setstripe -d $DIR/$tdir
22798         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22799                 error "Can't set directory default striping"
22800
22801         # exceed maximum stripe size
22802         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22803                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22804         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22805                 error "Able to create DoM component size more than LOD limit"
22806
22807         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22808         dom_current=$(do_facet mds1 $LCTL get_param -n \
22809                                                 lod.$mdtname.dom_stripesize)
22810         [ 0 -eq ${dom_current} ] ||
22811                 error "Can't set zero DoM stripe limit"
22812         rm $dom
22813
22814         # attempt to create DoM file on server with disabled DoM should
22815         # remove DoM entry from layout and be succeed
22816         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22817                 error "Can't create DoM file (DoM is disabled)"
22818         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22819                 error "File has DoM component while DoM is disabled"
22820         rm $dom
22821
22822         # attempt to create DoM file with only DoM stripe should return error
22823         $LFS setstripe -E $dom_limit -L mdt $dom &&
22824                 error "Able to create DoM-only file while DoM is disabled"
22825
22826         # too low values to be aligned with smallest stripe size 64K
22827         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22828         dom_current=$(do_facet mds1 $LCTL get_param -n \
22829                                                 lod.$mdtname.dom_stripesize)
22830         [ 30000 -eq ${dom_current} ] &&
22831                 error "Can set too small DoM stripe limit"
22832
22833         # 64K is a minimal stripe size in Lustre, expect limit of that size
22834         [ 65536 -eq ${dom_current} ] ||
22835                 error "Limit is not set to 64K but ${dom_current}"
22836
22837         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22838         dom_current=$(do_facet mds1 $LCTL get_param -n \
22839                                                 lod.$mdtname.dom_stripesize)
22840         echo $dom_current
22841         [ 2147483648 -eq ${dom_current} ] &&
22842                 error "Can set too large DoM stripe limit"
22843
22844         do_facet mds1 $LCTL set_param -n \
22845                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22846         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22847                 error "Can't create DoM component size after limit change"
22848         do_facet mds1 $LCTL set_param -n \
22849                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22850         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22851                 error "Can't create DoM file after limit decrease"
22852         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22853                 error "Can create big DoM component after limit decrease"
22854         touch ${dom}_def ||
22855                 error "Can't create file with old default layout"
22856
22857         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22858         return 0
22859 }
22860 run_test 270f "DoM: maximum DoM stripe size checks"
22861
22862 test_270g() {
22863         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22864                 skip "Need MDS version at least 2.13.52"
22865         local dom=$DIR/$tdir/$tfile
22866
22867         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22868         local lodname=${FSNAME}-MDT0000-mdtlov
22869
22870         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22871         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22872         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22873         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22874
22875         local dom_limit=1024
22876         local dom_threshold="50%"
22877
22878         $LFS setstripe -d $DIR/$tdir
22879         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22880                 error "Can't set directory default striping"
22881
22882         do_facet mds1 $LCTL set_param -n \
22883                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22884         # set 0 threshold and create DOM file to change tunable stripesize
22885         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22886         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22887                 error "Failed to create $dom file"
22888         # now tunable dom_cur_stripesize should reach maximum
22889         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22890                                         lod.${lodname}.dom_stripesize_cur_kb)
22891         [[ $dom_current == $dom_limit ]] ||
22892                 error "Current DOM stripesize is not maximum"
22893         rm $dom
22894
22895         # set threshold for further tests
22896         do_facet mds1 $LCTL set_param -n \
22897                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22898         echo "DOM threshold is $dom_threshold free space"
22899         local dom_def
22900         local dom_set
22901         # Spoof bfree to exceed threshold
22902         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22903         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22904         for spfree in 40 20 0 15 30 55; do
22905                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22906                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22907                         error "Failed to create $dom file"
22908                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22909                                         lod.${lodname}.dom_stripesize_cur_kb)
22910                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22911                 [[ $dom_def != $dom_current ]] ||
22912                         error "Default stripe size was not changed"
22913                 if (( spfree > 0 )) ; then
22914                         dom_set=$($LFS getstripe -S $dom)
22915                         (( dom_set == dom_def * 1024 )) ||
22916                                 error "DOM component size is still old"
22917                 else
22918                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22919                                 error "DoM component is set with no free space"
22920                 fi
22921                 rm $dom
22922                 dom_current=$dom_def
22923         done
22924 }
22925 run_test 270g "DoM: default DoM stripe size depends on free space"
22926
22927 test_270h() {
22928         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22929                 skip "Need MDS version at least 2.13.53"
22930
22931         local mdtname=${FSNAME}-MDT0000-mdtlov
22932         local dom=$DIR/$tdir/$tfile
22933         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22934
22935         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22936         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22937
22938         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22939         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22940                 error "can't create OST file"
22941         # mirrored file with DOM entry in the second mirror
22942         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22943                 error "can't create mirror with DoM component"
22944
22945         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22946
22947         # DOM component in the middle and has other enries in the same mirror,
22948         # should succeed but lost DoM component
22949         $LFS setstripe --copy=${dom}_1 $dom ||
22950                 error "Can't create file from OST|DOM mirror layout"
22951         # check new file has no DoM layout after all
22952         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22953                 error "File has DoM component while DoM is disabled"
22954 }
22955 run_test 270h "DoM: DoM stripe removal when disabled on server"
22956
22957 test_270i() {
22958         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22959                 skip "Need MDS version at least 2.14.54"
22960
22961         mkdir $DIR/$tdir
22962         # DoM with plain layout
22963         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22964                 error "default plain layout with DoM must fail"
22965         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
22966                 error "setstripe plain file layout with DoM must fail"
22967         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
22968                 error "default DoM layout with bad striping must fail"
22969         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
22970                 error "setstripe to DoM layout with bad striping must fail"
22971         return 0
22972 }
22973 run_test 270i "DoM: setting invalid DoM striping should fail"
22974
22975 test_271a() {
22976         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22977                 skip "Need MDS version at least 2.10.55"
22978
22979         local dom=$DIR/$tdir/dom
22980
22981         mkdir -p $DIR/$tdir
22982
22983         $LFS setstripe -E 1024K -L mdt $dom
22984
22985         lctl set_param -n mdc.*.stats=clear
22986         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22987         cat $dom > /dev/null
22988         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22989         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22990         ls $dom
22991         rm -f $dom
22992 }
22993 run_test 271a "DoM: data is cached for read after write"
22994
22995 test_271b() {
22996         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22997                 skip "Need MDS version at least 2.10.55"
22998
22999         local dom=$DIR/$tdir/dom
23000
23001         mkdir -p $DIR/$tdir
23002
23003         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23004
23005         lctl set_param -n mdc.*.stats=clear
23006         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23007         cancel_lru_locks mdc
23008         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23009         # second stat to check size is cached on client
23010         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23011         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23012         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23013         rm -f $dom
23014 }
23015 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23016
23017 test_271ba() {
23018         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23019                 skip "Need MDS version at least 2.10.55"
23020
23021         local dom=$DIR/$tdir/dom
23022
23023         mkdir -p $DIR/$tdir
23024
23025         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23026
23027         lctl set_param -n mdc.*.stats=clear
23028         lctl set_param -n osc.*.stats=clear
23029         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23030         cancel_lru_locks mdc
23031         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23032         # second stat to check size is cached on client
23033         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23034         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23035         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23036         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23037         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23038         rm -f $dom
23039 }
23040 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23041
23042
23043 get_mdc_stats() {
23044         local mdtidx=$1
23045         local param=$2
23046         local mdt=MDT$(printf %04x $mdtidx)
23047
23048         if [ -z $param ]; then
23049                 lctl get_param -n mdc.*$mdt*.stats
23050         else
23051                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23052         fi
23053 }
23054
23055 test_271c() {
23056         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23057                 skip "Need MDS version at least 2.10.55"
23058
23059         local dom=$DIR/$tdir/dom
23060
23061         mkdir -p $DIR/$tdir
23062
23063         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23064
23065         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23066         local facet=mds$((mdtidx + 1))
23067
23068         cancel_lru_locks mdc
23069         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23070         createmany -o $dom 1000
23071         lctl set_param -n mdc.*.stats=clear
23072         smalliomany -w $dom 1000 200
23073         get_mdc_stats $mdtidx
23074         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23075         # Each file has 1 open, 1 IO enqueues, total 2000
23076         # but now we have also +1 getxattr for security.capability, total 3000
23077         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23078         unlinkmany $dom 1000
23079
23080         cancel_lru_locks mdc
23081         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23082         createmany -o $dom 1000
23083         lctl set_param -n mdc.*.stats=clear
23084         smalliomany -w $dom 1000 200
23085         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23086         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23087         # for OPEN and IO lock.
23088         [ $((enq - enq_2)) -ge 1000 ] ||
23089                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23090         unlinkmany $dom 1000
23091         return 0
23092 }
23093 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23094
23095 cleanup_271def_tests() {
23096         trap 0
23097         rm -f $1
23098 }
23099
23100 test_271d() {
23101         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23102                 skip "Need MDS version at least 2.10.57"
23103
23104         local dom=$DIR/$tdir/dom
23105         local tmp=$TMP/$tfile
23106         trap "cleanup_271def_tests $tmp" EXIT
23107
23108         mkdir -p $DIR/$tdir
23109
23110         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23111
23112         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23113
23114         cancel_lru_locks mdc
23115         dd if=/dev/urandom of=$tmp bs=1000 count=1
23116         dd if=$tmp of=$dom bs=1000 count=1
23117         cancel_lru_locks mdc
23118
23119         cat /etc/hosts >> $tmp
23120         lctl set_param -n mdc.*.stats=clear
23121
23122         # append data to the same file it should update local page
23123         echo "Append to the same page"
23124         cat /etc/hosts >> $dom
23125         local num=$(get_mdc_stats $mdtidx ost_read)
23126         local ra=$(get_mdc_stats $mdtidx req_active)
23127         local rw=$(get_mdc_stats $mdtidx req_waittime)
23128
23129         [ -z $num ] || error "$num READ RPC occured"
23130         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23131         echo "... DONE"
23132
23133         # compare content
23134         cmp $tmp $dom || error "file miscompare"
23135
23136         cancel_lru_locks mdc
23137         lctl set_param -n mdc.*.stats=clear
23138
23139         echo "Open and read file"
23140         cat $dom > /dev/null
23141         local num=$(get_mdc_stats $mdtidx ost_read)
23142         local ra=$(get_mdc_stats $mdtidx req_active)
23143         local rw=$(get_mdc_stats $mdtidx req_waittime)
23144
23145         [ -z $num ] || error "$num READ RPC occured"
23146         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23147         echo "... DONE"
23148
23149         # compare content
23150         cmp $tmp $dom || error "file miscompare"
23151
23152         return 0
23153 }
23154 run_test 271d "DoM: read on open (1K file in reply buffer)"
23155
23156 test_271f() {
23157         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23158                 skip "Need MDS version at least 2.10.57"
23159
23160         local dom=$DIR/$tdir/dom
23161         local tmp=$TMP/$tfile
23162         trap "cleanup_271def_tests $tmp" EXIT
23163
23164         mkdir -p $DIR/$tdir
23165
23166         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23167
23168         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23169
23170         cancel_lru_locks mdc
23171         dd if=/dev/urandom of=$tmp bs=265000 count=1
23172         dd if=$tmp of=$dom bs=265000 count=1
23173         cancel_lru_locks mdc
23174         cat /etc/hosts >> $tmp
23175         lctl set_param -n mdc.*.stats=clear
23176
23177         echo "Append to the same page"
23178         cat /etc/hosts >> $dom
23179         local num=$(get_mdc_stats $mdtidx ost_read)
23180         local ra=$(get_mdc_stats $mdtidx req_active)
23181         local rw=$(get_mdc_stats $mdtidx req_waittime)
23182
23183         [ -z $num ] || error "$num READ RPC occured"
23184         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23185         echo "... DONE"
23186
23187         # compare content
23188         cmp $tmp $dom || error "file miscompare"
23189
23190         cancel_lru_locks mdc
23191         lctl set_param -n mdc.*.stats=clear
23192
23193         echo "Open and read file"
23194         cat $dom > /dev/null
23195         local num=$(get_mdc_stats $mdtidx ost_read)
23196         local ra=$(get_mdc_stats $mdtidx req_active)
23197         local rw=$(get_mdc_stats $mdtidx req_waittime)
23198
23199         [ -z $num ] && num=0
23200         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23201         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23202         echo "... DONE"
23203
23204         # compare content
23205         cmp $tmp $dom || error "file miscompare"
23206
23207         return 0
23208 }
23209 run_test 271f "DoM: read on open (200K file and read tail)"
23210
23211 test_271g() {
23212         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23213                 skip "Skipping due to old client or server version"
23214
23215         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23216         # to get layout
23217         $CHECKSTAT -t file $DIR1/$tfile
23218
23219         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23220         MULTIOP_PID=$!
23221         sleep 1
23222         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23223         $LCTL set_param fail_loc=0x80000314
23224         rm $DIR1/$tfile || error "Unlink fails"
23225         RC=$?
23226         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23227         [ $RC -eq 0 ] || error "Failed write to stale object"
23228 }
23229 run_test 271g "Discard DoM data vs client flush race"
23230
23231 test_272a() {
23232         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23233                 skip "Need MDS version at least 2.11.50"
23234
23235         local dom=$DIR/$tdir/dom
23236         mkdir -p $DIR/$tdir
23237
23238         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23239         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23240                 error "failed to write data into $dom"
23241         local old_md5=$(md5sum $dom)
23242
23243         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23244                 error "failed to migrate to the same DoM component"
23245
23246         local new_md5=$(md5sum $dom)
23247
23248         [ "$old_md5" == "$new_md5" ] ||
23249                 error "md5sum differ: $old_md5, $new_md5"
23250
23251         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23252                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23253 }
23254 run_test 272a "DoM migration: new layout with the same DOM component"
23255
23256 test_272b() {
23257         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23258                 skip "Need MDS version at least 2.11.50"
23259
23260         local dom=$DIR/$tdir/dom
23261         mkdir -p $DIR/$tdir
23262         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23263
23264         local mdtidx=$($LFS getstripe -m $dom)
23265         local mdtname=MDT$(printf %04x $mdtidx)
23266         local facet=mds$((mdtidx + 1))
23267
23268         local mdtfree1=$(do_facet $facet \
23269                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23270         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23271                 error "failed to write data into $dom"
23272         local old_md5=$(md5sum $dom)
23273         cancel_lru_locks mdc
23274         local mdtfree1=$(do_facet $facet \
23275                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23276
23277         $LFS migrate -c2 $dom ||
23278                 error "failed to migrate to the new composite layout"
23279         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23280                 error "MDT stripe was not removed"
23281
23282         cancel_lru_locks mdc
23283         local new_md5=$(md5sum $dom)
23284         [ "$old_md5" == "$new_md5" ] ||
23285                 error "$old_md5 != $new_md5"
23286
23287         # Skip free space checks with ZFS
23288         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23289                 local mdtfree2=$(do_facet $facet \
23290                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23291                 [ $mdtfree2 -gt $mdtfree1 ] ||
23292                         error "MDT space is not freed after migration"
23293         fi
23294         return 0
23295 }
23296 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23297
23298 test_272c() {
23299         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23300                 skip "Need MDS version at least 2.11.50"
23301
23302         local dom=$DIR/$tdir/$tfile
23303         mkdir -p $DIR/$tdir
23304         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23305
23306         local mdtidx=$($LFS getstripe -m $dom)
23307         local mdtname=MDT$(printf %04x $mdtidx)
23308         local facet=mds$((mdtidx + 1))
23309
23310         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23311                 error "failed to write data into $dom"
23312         local old_md5=$(md5sum $dom)
23313         cancel_lru_locks mdc
23314         local mdtfree1=$(do_facet $facet \
23315                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23316
23317         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23318                 error "failed to migrate to the new composite layout"
23319         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23320                 error "MDT stripe was not removed"
23321
23322         cancel_lru_locks mdc
23323         local new_md5=$(md5sum $dom)
23324         [ "$old_md5" == "$new_md5" ] ||
23325                 error "$old_md5 != $new_md5"
23326
23327         # Skip free space checks with ZFS
23328         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23329                 local mdtfree2=$(do_facet $facet \
23330                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23331                 [ $mdtfree2 -gt $mdtfree1 ] ||
23332                         error "MDS space is not freed after migration"
23333         fi
23334         return 0
23335 }
23336 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23337
23338 test_272d() {
23339         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23340                 skip "Need MDS version at least 2.12.55"
23341
23342         local dom=$DIR/$tdir/$tfile
23343         mkdir -p $DIR/$tdir
23344         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23345
23346         local mdtidx=$($LFS getstripe -m $dom)
23347         local mdtname=MDT$(printf %04x $mdtidx)
23348         local facet=mds$((mdtidx + 1))
23349
23350         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23351                 error "failed to write data into $dom"
23352         local old_md5=$(md5sum $dom)
23353         cancel_lru_locks mdc
23354         local mdtfree1=$(do_facet $facet \
23355                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23356
23357         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23358                 error "failed mirroring to the new composite layout"
23359         $LFS mirror resync $dom ||
23360                 error "failed mirror resync"
23361         $LFS mirror split --mirror-id 1 -d $dom ||
23362                 error "failed mirror split"
23363
23364         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23365                 error "MDT stripe was not removed"
23366
23367         cancel_lru_locks mdc
23368         local new_md5=$(md5sum $dom)
23369         [ "$old_md5" == "$new_md5" ] ||
23370                 error "$old_md5 != $new_md5"
23371
23372         # Skip free space checks with ZFS
23373         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23374                 local mdtfree2=$(do_facet $facet \
23375                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23376                 [ $mdtfree2 -gt $mdtfree1 ] ||
23377                         error "MDS space is not freed after DOM mirror deletion"
23378         fi
23379         return 0
23380 }
23381 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23382
23383 test_272e() {
23384         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23385                 skip "Need MDS version at least 2.12.55"
23386
23387         local dom=$DIR/$tdir/$tfile
23388         mkdir -p $DIR/$tdir
23389         $LFS setstripe -c 2 $dom
23390
23391         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23392                 error "failed to write data into $dom"
23393         local old_md5=$(md5sum $dom)
23394         cancel_lru_locks
23395
23396         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23397                 error "failed mirroring to the DOM layout"
23398         $LFS mirror resync $dom ||
23399                 error "failed mirror resync"
23400         $LFS mirror split --mirror-id 1 -d $dom ||
23401                 error "failed mirror split"
23402
23403         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23404                 error "MDT stripe wasn't set"
23405
23406         cancel_lru_locks
23407         local new_md5=$(md5sum $dom)
23408         [ "$old_md5" == "$new_md5" ] ||
23409                 error "$old_md5 != $new_md5"
23410
23411         return 0
23412 }
23413 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23414
23415 test_272f() {
23416         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23417                 skip "Need MDS version at least 2.12.55"
23418
23419         local dom=$DIR/$tdir/$tfile
23420         mkdir -p $DIR/$tdir
23421         $LFS setstripe -c 2 $dom
23422
23423         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23424                 error "failed to write data into $dom"
23425         local old_md5=$(md5sum $dom)
23426         cancel_lru_locks
23427
23428         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23429                 error "failed migrating to the DOM file"
23430
23431         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23432                 error "MDT stripe wasn't set"
23433
23434         cancel_lru_locks
23435         local new_md5=$(md5sum $dom)
23436         [ "$old_md5" != "$new_md5" ] &&
23437                 error "$old_md5 != $new_md5"
23438
23439         return 0
23440 }
23441 run_test 272f "DoM migration: OST-striped file to DOM file"
23442
23443 test_273a() {
23444         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23445                 skip "Need MDS version at least 2.11.50"
23446
23447         # Layout swap cannot be done if either file has DOM component,
23448         # this will never be supported, migration should be used instead
23449
23450         local dom=$DIR/$tdir/$tfile
23451         mkdir -p $DIR/$tdir
23452
23453         $LFS setstripe -c2 ${dom}_plain
23454         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23455         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23456                 error "can swap layout with DoM component"
23457         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23458                 error "can swap layout with DoM component"
23459
23460         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23461         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23462                 error "can swap layout with DoM component"
23463         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23464                 error "can swap layout with DoM component"
23465         return 0
23466 }
23467 run_test 273a "DoM: layout swapping should fail with DOM"
23468
23469 test_273b() {
23470         mkdir -p $DIR/$tdir
23471         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23472
23473 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23474         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23475
23476         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23477 }
23478 run_test 273b "DoM: race writeback and object destroy"
23479
23480 test_275() {
23481         remote_ost_nodsh && skip "remote OST with nodsh"
23482         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23483                 skip "Need OST version >= 2.10.57"
23484
23485         local file=$DIR/$tfile
23486         local oss
23487
23488         oss=$(comma_list $(osts_nodes))
23489
23490         dd if=/dev/urandom of=$file bs=1M count=2 ||
23491                 error "failed to create a file"
23492         cancel_lru_locks osc
23493
23494         #lock 1
23495         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23496                 error "failed to read a file"
23497
23498 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23499         $LCTL set_param fail_loc=0x8000031f
23500
23501         cancel_lru_locks osc &
23502         sleep 1
23503
23504 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23505         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23506         #IO takes another lock, but matches the PENDING one
23507         #and places it to the IO RPC
23508         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23509                 error "failed to read a file with PENDING lock"
23510 }
23511 run_test 275 "Read on a canceled duplicate lock"
23512
23513 test_276() {
23514         remote_ost_nodsh && skip "remote OST with nodsh"
23515         local pid
23516
23517         do_facet ost1 "(while true; do \
23518                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23519                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23520         pid=$!
23521
23522         for LOOP in $(seq 20); do
23523                 stop ost1
23524                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23525         done
23526         kill -9 $pid
23527         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23528                 rm $TMP/sanity_276_pid"
23529 }
23530 run_test 276 "Race between mount and obd_statfs"
23531
23532 test_277() {
23533         $LCTL set_param ldlm.namespaces.*.lru_size=0
23534         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23535         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23536                         grep ^used_mb | awk '{print $2}')
23537         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23538         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23539                 oflag=direct conv=notrunc
23540         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23541                         grep ^used_mb | awk '{print $2}')
23542         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23543 }
23544 run_test 277 "Direct IO shall drop page cache"
23545
23546 test_278() {
23547         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23548         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23549         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23550                 skip "needs the same host for mdt1 mdt2" && return
23551
23552         local pid1
23553         local pid2
23554
23555 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23556         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23557         stop mds2 &
23558         pid2=$!
23559
23560         stop mds1
23561
23562         echo "Starting MDTs"
23563         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23564         wait $pid2
23565 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23566 #will return NULL
23567         do_facet mds2 $LCTL set_param fail_loc=0
23568
23569         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23570         wait_recovery_complete mds2
23571 }
23572 run_test 278 "Race starting MDS between MDTs stop/start"
23573
23574 test_280() {
23575         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23576                 skip "Need MGS version at least 2.13.52"
23577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23578         combined_mgs_mds || skip "needs combined MGS/MDT"
23579
23580         umount_client $MOUNT
23581 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23582         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23583
23584         mount_client $MOUNT &
23585         sleep 1
23586         stop mgs || error "stop mgs failed"
23587         #for a race mgs would crash
23588         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23589         # make sure we unmount client before remounting
23590         wait
23591         umount_client $MOUNT
23592         mount_client $MOUNT || error "mount client failed"
23593 }
23594 run_test 280 "Race between MGS umount and client llog processing"
23595
23596 cleanup_test_300() {
23597         trap 0
23598         umask $SAVE_UMASK
23599 }
23600 test_striped_dir() {
23601         local mdt_index=$1
23602         local stripe_count
23603         local stripe_index
23604
23605         mkdir -p $DIR/$tdir
23606
23607         SAVE_UMASK=$(umask)
23608         trap cleanup_test_300 RETURN EXIT
23609
23610         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23611                                                 $DIR/$tdir/striped_dir ||
23612                 error "set striped dir error"
23613
23614         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23615         [ "$mode" = "755" ] || error "expect 755 got $mode"
23616
23617         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23618                 error "getdirstripe failed"
23619         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23620         if [ "$stripe_count" != "2" ]; then
23621                 error "1:stripe_count is $stripe_count, expect 2"
23622         fi
23623         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23624         if [ "$stripe_count" != "2" ]; then
23625                 error "2:stripe_count is $stripe_count, expect 2"
23626         fi
23627
23628         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23629         if [ "$stripe_index" != "$mdt_index" ]; then
23630                 error "stripe_index is $stripe_index, expect $mdt_index"
23631         fi
23632
23633         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23634                 error "nlink error after create striped dir"
23635
23636         mkdir $DIR/$tdir/striped_dir/a
23637         mkdir $DIR/$tdir/striped_dir/b
23638
23639         stat $DIR/$tdir/striped_dir/a ||
23640                 error "create dir under striped dir failed"
23641         stat $DIR/$tdir/striped_dir/b ||
23642                 error "create dir under striped dir failed"
23643
23644         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23645                 error "nlink error after mkdir"
23646
23647         rmdir $DIR/$tdir/striped_dir/a
23648         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23649                 error "nlink error after rmdir"
23650
23651         rmdir $DIR/$tdir/striped_dir/b
23652         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23653                 error "nlink error after rmdir"
23654
23655         chattr +i $DIR/$tdir/striped_dir
23656         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23657                 error "immutable flags not working under striped dir!"
23658         chattr -i $DIR/$tdir/striped_dir
23659
23660         rmdir $DIR/$tdir/striped_dir ||
23661                 error "rmdir striped dir error"
23662
23663         cleanup_test_300
23664
23665         true
23666 }
23667
23668 test_300a() {
23669         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23670                 skip "skipped for lustre < 2.7.0"
23671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23673
23674         test_striped_dir 0 || error "failed on striped dir on MDT0"
23675         test_striped_dir 1 || error "failed on striped dir on MDT0"
23676 }
23677 run_test 300a "basic striped dir sanity test"
23678
23679 test_300b() {
23680         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23681                 skip "skipped for lustre < 2.7.0"
23682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23684
23685         local i
23686         local mtime1
23687         local mtime2
23688         local mtime3
23689
23690         test_mkdir $DIR/$tdir || error "mkdir fail"
23691         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23692                 error "set striped dir error"
23693         for i in {0..9}; do
23694                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23695                 sleep 1
23696                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23697                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23698                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23699                 sleep 1
23700                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23701                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23702                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23703         done
23704         true
23705 }
23706 run_test 300b "check ctime/mtime for striped dir"
23707
23708 test_300c() {
23709         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23710                 skip "skipped for lustre < 2.7.0"
23711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23713
23714         local file_count
23715
23716         mkdir_on_mdt0 $DIR/$tdir
23717         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23718                 error "set striped dir error"
23719
23720         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23721                 error "chown striped dir failed"
23722
23723         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23724                 error "create 5k files failed"
23725
23726         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23727
23728         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23729
23730         rm -rf $DIR/$tdir
23731 }
23732 run_test 300c "chown && check ls under striped directory"
23733
23734 test_300d() {
23735         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23736                 skip "skipped for lustre < 2.7.0"
23737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23738         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23739
23740         local stripe_count
23741         local file
23742
23743         mkdir -p $DIR/$tdir
23744         $LFS setstripe -c 2 $DIR/$tdir
23745
23746         #local striped directory
23747         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23748                 error "set striped dir error"
23749         #look at the directories for debug purposes
23750         ls -l $DIR/$tdir
23751         $LFS getdirstripe $DIR/$tdir
23752         ls -l $DIR/$tdir/striped_dir
23753         $LFS getdirstripe $DIR/$tdir/striped_dir
23754         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23755                 error "create 10 files failed"
23756
23757         #remote striped directory
23758         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23759                 error "set striped dir error"
23760         #look at the directories for debug purposes
23761         ls -l $DIR/$tdir
23762         $LFS getdirstripe $DIR/$tdir
23763         ls -l $DIR/$tdir/remote_striped_dir
23764         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23765         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23766                 error "create 10 files failed"
23767
23768         for file in $(find $DIR/$tdir); do
23769                 stripe_count=$($LFS getstripe -c $file)
23770                 [ $stripe_count -eq 2 ] ||
23771                         error "wrong stripe $stripe_count for $file"
23772         done
23773
23774         rm -rf $DIR/$tdir
23775 }
23776 run_test 300d "check default stripe under striped directory"
23777
23778 test_300e() {
23779         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23780                 skip "Need MDS version at least 2.7.55"
23781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23783
23784         local stripe_count
23785         local file
23786
23787         mkdir -p $DIR/$tdir
23788
23789         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23790                 error "set striped dir error"
23791
23792         touch $DIR/$tdir/striped_dir/a
23793         touch $DIR/$tdir/striped_dir/b
23794         touch $DIR/$tdir/striped_dir/c
23795
23796         mkdir $DIR/$tdir/striped_dir/dir_a
23797         mkdir $DIR/$tdir/striped_dir/dir_b
23798         mkdir $DIR/$tdir/striped_dir/dir_c
23799
23800         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23801                 error "set striped adir under striped dir error"
23802
23803         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23804                 error "set striped bdir under striped dir error"
23805
23806         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23807                 error "set striped cdir under striped dir error"
23808
23809         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23810                 error "rename dir under striped dir fails"
23811
23812         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23813                 error "rename dir under different stripes fails"
23814
23815         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23816                 error "rename file under striped dir should succeed"
23817
23818         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23819                 error "rename dir under striped dir should succeed"
23820
23821         rm -rf $DIR/$tdir
23822 }
23823 run_test 300e "check rename under striped directory"
23824
23825 test_300f() {
23826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23828         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23829                 skip "Need MDS version at least 2.7.55"
23830
23831         local stripe_count
23832         local file
23833
23834         rm -rf $DIR/$tdir
23835         mkdir -p $DIR/$tdir
23836
23837         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23838                 error "set striped dir error"
23839
23840         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23841                 error "set striped dir error"
23842
23843         touch $DIR/$tdir/striped_dir/a
23844         mkdir $DIR/$tdir/striped_dir/dir_a
23845         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23846                 error "create striped dir under striped dir fails"
23847
23848         touch $DIR/$tdir/striped_dir1/b
23849         mkdir $DIR/$tdir/striped_dir1/dir_b
23850         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23851                 error "create striped dir under striped dir fails"
23852
23853         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23854                 error "rename dir under different striped dir should fail"
23855
23856         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23857                 error "rename striped dir under diff striped dir should fail"
23858
23859         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23860                 error "rename file under diff striped dirs fails"
23861
23862         rm -rf $DIR/$tdir
23863 }
23864 run_test 300f "check rename cross striped directory"
23865
23866 test_300_check_default_striped_dir()
23867 {
23868         local dirname=$1
23869         local default_count=$2
23870         local default_index=$3
23871         local stripe_count
23872         local stripe_index
23873         local dir_stripe_index
23874         local dir
23875
23876         echo "checking $dirname $default_count $default_index"
23877         $LFS setdirstripe -D -c $default_count -i $default_index \
23878                                 -H all_char $DIR/$tdir/$dirname ||
23879                 error "set default stripe on striped dir error"
23880         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23881         [ $stripe_count -eq $default_count ] ||
23882                 error "expect $default_count get $stripe_count for $dirname"
23883
23884         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23885         [ $stripe_index -eq $default_index ] ||
23886                 error "expect $default_index get $stripe_index for $dirname"
23887
23888         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23889                                                 error "create dirs failed"
23890
23891         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23892         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23893         for dir in $(find $DIR/$tdir/$dirname/*); do
23894                 stripe_count=$($LFS getdirstripe -c $dir)
23895                 (( $stripe_count == $default_count )) ||
23896                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23897                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23898                 error "stripe count $default_count != $stripe_count for $dir"
23899
23900                 stripe_index=$($LFS getdirstripe -i $dir)
23901                 [ $default_index -eq -1 ] ||
23902                         [ $stripe_index -eq $default_index ] ||
23903                         error "$stripe_index != $default_index for $dir"
23904
23905                 #check default stripe
23906                 stripe_count=$($LFS getdirstripe -D -c $dir)
23907                 [ $stripe_count -eq $default_count ] ||
23908                 error "default count $default_count != $stripe_count for $dir"
23909
23910                 stripe_index=$($LFS getdirstripe -D -i $dir)
23911                 [ $stripe_index -eq $default_index ] ||
23912                 error "default index $default_index != $stripe_index for $dir"
23913         done
23914         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23915 }
23916
23917 test_300g() {
23918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23919         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23920                 skip "Need MDS version at least 2.7.55"
23921
23922         local dir
23923         local stripe_count
23924         local stripe_index
23925
23926         mkdir_on_mdt0 $DIR/$tdir
23927         mkdir $DIR/$tdir/normal_dir
23928
23929         #Checking when client cache stripe index
23930         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23931         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23932                 error "create striped_dir failed"
23933
23934         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23935                 error "create dir0 fails"
23936         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23937         [ $stripe_index -eq 0 ] ||
23938                 error "dir0 expect index 0 got $stripe_index"
23939
23940         mkdir $DIR/$tdir/striped_dir/dir1 ||
23941                 error "create dir1 fails"
23942         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23943         [ $stripe_index -eq 1 ] ||
23944                 error "dir1 expect index 1 got $stripe_index"
23945
23946         #check default stripe count/stripe index
23947         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23948         test_300_check_default_striped_dir normal_dir 1 0
23949         test_300_check_default_striped_dir normal_dir -1 1
23950         test_300_check_default_striped_dir normal_dir 2 -1
23951
23952         #delete default stripe information
23953         echo "delete default stripeEA"
23954         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23955                 error "set default stripe on striped dir error"
23956
23957         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23958         for dir in $(find $DIR/$tdir/normal_dir/*); do
23959                 stripe_count=$($LFS getdirstripe -c $dir)
23960                 [ $stripe_count -eq 0 ] ||
23961                         error "expect 1 get $stripe_count for $dir"
23962         done
23963 }
23964 run_test 300g "check default striped directory for normal directory"
23965
23966 test_300h() {
23967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23968         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23969                 skip "Need MDS version at least 2.7.55"
23970
23971         local dir
23972         local stripe_count
23973
23974         mkdir $DIR/$tdir
23975         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23976                 error "set striped dir error"
23977
23978         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23979         test_300_check_default_striped_dir striped_dir 1 0
23980         test_300_check_default_striped_dir striped_dir -1 1
23981         test_300_check_default_striped_dir striped_dir 2 -1
23982
23983         #delete default stripe information
23984         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23985                 error "set default stripe on striped dir error"
23986
23987         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23988         for dir in $(find $DIR/$tdir/striped_dir/*); do
23989                 stripe_count=$($LFS getdirstripe -c $dir)
23990                 [ $stripe_count -eq 0 ] ||
23991                         error "expect 1 get $stripe_count for $dir"
23992         done
23993 }
23994 run_test 300h "check default striped directory for striped directory"
23995
23996 test_300i() {
23997         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23998         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23999         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24000                 skip "Need MDS version at least 2.7.55"
24001
24002         local stripe_count
24003         local file
24004
24005         mkdir $DIR/$tdir
24006
24007         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24008                 error "set striped dir error"
24009
24010         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24011                 error "create files under striped dir failed"
24012
24013         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24014                 error "set striped hashdir error"
24015
24016         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24017                 error "create dir0 under hash dir failed"
24018         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24019                 error "create dir1 under hash dir failed"
24020         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24021                 error "create dir2 under hash dir failed"
24022
24023         # unfortunately, we need to umount to clear dir layout cache for now
24024         # once we fully implement dir layout, we can drop this
24025         umount_client $MOUNT || error "umount failed"
24026         mount_client $MOUNT || error "mount failed"
24027
24028         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24029         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24030         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24031
24032         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24033                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24034                         error "create crush2 dir $tdir/hashdir/d3 failed"
24035                 $LFS find -H crush2 $DIR/$tdir/hashdir
24036                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24037                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24038
24039                 # mkdir with an invalid hash type (hash=fail_val) from client
24040                 # should be replaced on MDS with a valid (default) hash type
24041                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24042                 $LCTL set_param fail_loc=0x1901 fail_val=99
24043                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24044
24045                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24046                 local expect=$(do_facet mds1 \
24047                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24048                 [[ $hash == $expect ]] ||
24049                         error "d99 hash '$hash' != expected hash '$expect'"
24050         fi
24051
24052         #set the stripe to be unknown hash type on read
24053         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24054         $LCTL set_param fail_loc=0x1901 fail_val=99
24055         for ((i = 0; i < 10; i++)); do
24056                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24057                         error "stat f-$i failed"
24058                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24059         done
24060
24061         touch $DIR/$tdir/striped_dir/f0 &&
24062                 error "create under striped dir with unknown hash should fail"
24063
24064         $LCTL set_param fail_loc=0
24065
24066         umount_client $MOUNT || error "umount failed"
24067         mount_client $MOUNT || error "mount failed"
24068
24069         return 0
24070 }
24071 run_test 300i "client handle unknown hash type striped directory"
24072
24073 test_300j() {
24074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24076         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24077                 skip "Need MDS version at least 2.7.55"
24078
24079         local stripe_count
24080         local file
24081
24082         mkdir $DIR/$tdir
24083
24084         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24085         $LCTL set_param fail_loc=0x1702
24086         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24087                 error "set striped dir error"
24088
24089         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24090                 error "create files under striped dir failed"
24091
24092         $LCTL set_param fail_loc=0
24093
24094         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24095
24096         return 0
24097 }
24098 run_test 300j "test large update record"
24099
24100 test_300k() {
24101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24103         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24104                 skip "Need MDS version at least 2.7.55"
24105
24106         # this test needs a huge transaction
24107         local kb
24108         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24109              osd*.$FSNAME-MDT0000.kbytestotal")
24110         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24111
24112         local stripe_count
24113         local file
24114
24115         mkdir $DIR/$tdir
24116
24117         #define OBD_FAIL_LARGE_STRIPE   0x1703
24118         $LCTL set_param fail_loc=0x1703
24119         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24120                 error "set striped dir error"
24121         $LCTL set_param fail_loc=0
24122
24123         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24124                 error "getstripeddir fails"
24125         rm -rf $DIR/$tdir/striped_dir ||
24126                 error "unlink striped dir fails"
24127
24128         return 0
24129 }
24130 run_test 300k "test large striped directory"
24131
24132 test_300l() {
24133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24135         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24136                 skip "Need MDS version at least 2.7.55"
24137
24138         local stripe_index
24139
24140         test_mkdir -p $DIR/$tdir/striped_dir
24141         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24142                         error "chown $RUNAS_ID failed"
24143         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24144                 error "set default striped dir failed"
24145
24146         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24147         $LCTL set_param fail_loc=0x80000158
24148         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24149
24150         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24151         [ $stripe_index -eq 1 ] ||
24152                 error "expect 1 get $stripe_index for $dir"
24153 }
24154 run_test 300l "non-root user to create dir under striped dir with stale layout"
24155
24156 test_300m() {
24157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24158         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24159         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24160                 skip "Need MDS version at least 2.7.55"
24161
24162         mkdir -p $DIR/$tdir/striped_dir
24163         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24164                 error "set default stripes dir error"
24165
24166         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24167
24168         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24169         [ $stripe_count -eq 0 ] ||
24170                         error "expect 0 get $stripe_count for a"
24171
24172         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24173                 error "set default stripes dir error"
24174
24175         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24176
24177         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24178         [ $stripe_count -eq 0 ] ||
24179                         error "expect 0 get $stripe_count for b"
24180
24181         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24182                 error "set default stripes dir error"
24183
24184         mkdir $DIR/$tdir/striped_dir/c &&
24185                 error "default stripe_index is invalid, mkdir c should fails"
24186
24187         rm -rf $DIR/$tdir || error "rmdir fails"
24188 }
24189 run_test 300m "setstriped directory on single MDT FS"
24190
24191 cleanup_300n() {
24192         local list=$(comma_list $(mdts_nodes))
24193
24194         trap 0
24195         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24196 }
24197
24198 test_300n() {
24199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24201         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24202                 skip "Need MDS version at least 2.7.55"
24203         remote_mds_nodsh && skip "remote MDS with nodsh"
24204
24205         local stripe_index
24206         local list=$(comma_list $(mdts_nodes))
24207
24208         trap cleanup_300n RETURN EXIT
24209         mkdir -p $DIR/$tdir
24210         chmod 777 $DIR/$tdir
24211         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24212                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24213                 error "create striped dir succeeds with gid=0"
24214
24215         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24216         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24217                 error "create striped dir fails with gid=-1"
24218
24219         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24220         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24221                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24222                 error "set default striped dir succeeds with gid=0"
24223
24224
24225         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24226         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24227                 error "set default striped dir fails with gid=-1"
24228
24229
24230         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24231         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24232                                         error "create test_dir fails"
24233         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24234                                         error "create test_dir1 fails"
24235         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24236                                         error "create test_dir2 fails"
24237         cleanup_300n
24238 }
24239 run_test 300n "non-root user to create dir under striped dir with default EA"
24240
24241 test_300o() {
24242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24244         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24245                 skip "Need MDS version at least 2.7.55"
24246
24247         local numfree1
24248         local numfree2
24249
24250         mkdir -p $DIR/$tdir
24251
24252         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24253         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24254         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24255                 skip "not enough free inodes $numfree1 $numfree2"
24256         fi
24257
24258         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24259         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24260         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24261                 skip "not enough free space $numfree1 $numfree2"
24262         fi
24263
24264         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24265                 error "setdirstripe fails"
24266
24267         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24268                 error "create dirs fails"
24269
24270         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24271         ls $DIR/$tdir/striped_dir > /dev/null ||
24272                 error "ls striped dir fails"
24273         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24274                 error "unlink big striped dir fails"
24275 }
24276 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24277
24278 test_300p() {
24279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24281         remote_mds_nodsh && skip "remote MDS with nodsh"
24282
24283         mkdir_on_mdt0 $DIR/$tdir
24284
24285         #define OBD_FAIL_OUT_ENOSPC     0x1704
24286         do_facet mds2 lctl set_param fail_loc=0x80001704
24287         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24288                  && error "create striped directory should fail"
24289
24290         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24291
24292         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24293         true
24294 }
24295 run_test 300p "create striped directory without space"
24296
24297 test_300q() {
24298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24300
24301         local fd=$(free_fd)
24302         local cmd="exec $fd<$tdir"
24303         cd $DIR
24304         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24305         eval $cmd
24306         cmd="exec $fd<&-"
24307         trap "eval $cmd" EXIT
24308         cd $tdir || error "cd $tdir fails"
24309         rmdir  ../$tdir || error "rmdir $tdir fails"
24310         mkdir local_dir && error "create dir succeeds"
24311         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24312         eval $cmd
24313         return 0
24314 }
24315 run_test 300q "create remote directory under orphan directory"
24316
24317 test_300r() {
24318         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24319                 skip "Need MDS version at least 2.7.55" && return
24320         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24321
24322         mkdir $DIR/$tdir
24323
24324         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24325                 error "set striped dir error"
24326
24327         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24328                 error "getstripeddir fails"
24329
24330         local stripe_count
24331         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24332                       awk '/lmv_stripe_count:/ { print $2 }')
24333
24334         [ $MDSCOUNT -ne $stripe_count ] &&
24335                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24336
24337         rm -rf $DIR/$tdir/striped_dir ||
24338                 error "unlink striped dir fails"
24339 }
24340 run_test 300r "test -1 striped directory"
24341
24342 test_300s_helper() {
24343         local count=$1
24344
24345         local stripe_dir=$DIR/$tdir/striped_dir.$count
24346
24347         $LFS mkdir -c $count $stripe_dir ||
24348                 error "lfs mkdir -c error"
24349
24350         $LFS getdirstripe $stripe_dir ||
24351                 error "lfs getdirstripe fails"
24352
24353         local stripe_count
24354         stripe_count=$($LFS getdirstripe $stripe_dir |
24355                       awk '/lmv_stripe_count:/ { print $2 }')
24356
24357         [ $count -ne $stripe_count ] &&
24358                 error_noexit "bad stripe count $stripe_count expected $count"
24359
24360         local dupe_stripes
24361         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24362                 awk '/0x/ {count[$1] += 1}; END {
24363                         for (idx in count) {
24364                                 if (count[idx]>1) {
24365                                         print "index " idx " count " count[idx]
24366                                 }
24367                         }
24368                 }')
24369
24370         if [[ -n "$dupe_stripes" ]] ; then
24371                 lfs getdirstripe $stripe_dir
24372                 error_noexit "Dupe MDT above: $dupe_stripes "
24373         fi
24374
24375         rm -rf $stripe_dir ||
24376                 error_noexit "unlink $stripe_dir fails"
24377 }
24378
24379 test_300s() {
24380         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24381                 skip "Need MDS version at least 2.7.55" && return
24382         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24383
24384         mkdir $DIR/$tdir
24385         for count in $(seq 2 $MDSCOUNT); do
24386                 test_300s_helper $count
24387         done
24388 }
24389 run_test 300s "test lfs mkdir -c without -i"
24390
24391 test_300t() {
24392         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24393                 skip "need MDS 2.14.55 or later"
24394         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24395
24396         local testdir="$DIR/$tdir/striped_dir"
24397         local dir1=$testdir/dir1
24398         local dir2=$testdir/dir2
24399
24400         mkdir -p $testdir
24401
24402         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24403                 error "failed to set default stripe count for $testdir"
24404
24405         mkdir $dir1
24406         local stripe_count=$($LFS getdirstripe -c $dir1)
24407
24408         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24409
24410         local max_count=$((MDSCOUNT - 1))
24411         local mdts=$(comma_list $(mdts_nodes))
24412
24413         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24414         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24415
24416         mkdir $dir2
24417         stripe_count=$($LFS getdirstripe -c $dir2)
24418
24419         (( $stripe_count == $max_count )) || error "wrong stripe count"
24420 }
24421 run_test 300t "test max_mdt_stripecount"
24422
24423 prepare_remote_file() {
24424         mkdir $DIR/$tdir/src_dir ||
24425                 error "create remote source failed"
24426
24427         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24428                  error "cp to remote source failed"
24429         touch $DIR/$tdir/src_dir/a
24430
24431         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24432                 error "create remote target dir failed"
24433
24434         touch $DIR/$tdir/tgt_dir/b
24435
24436         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24437                 error "rename dir cross MDT failed!"
24438
24439         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24440                 error "src_child still exists after rename"
24441
24442         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24443                 error "missing file(a) after rename"
24444
24445         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24446                 error "diff after rename"
24447 }
24448
24449 test_310a() {
24450         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24452
24453         local remote_file=$DIR/$tdir/tgt_dir/b
24454
24455         mkdir -p $DIR/$tdir
24456
24457         prepare_remote_file || error "prepare remote file failed"
24458
24459         #open-unlink file
24460         $OPENUNLINK $remote_file $remote_file ||
24461                 error "openunlink $remote_file failed"
24462         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24463 }
24464 run_test 310a "open unlink remote file"
24465
24466 test_310b() {
24467         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24469
24470         local remote_file=$DIR/$tdir/tgt_dir/b
24471
24472         mkdir -p $DIR/$tdir
24473
24474         prepare_remote_file || error "prepare remote file failed"
24475
24476         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24477         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24478         $CHECKSTAT -t file $remote_file || error "check file failed"
24479 }
24480 run_test 310b "unlink remote file with multiple links while open"
24481
24482 test_310c() {
24483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24484         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24485
24486         local remote_file=$DIR/$tdir/tgt_dir/b
24487
24488         mkdir -p $DIR/$tdir
24489
24490         prepare_remote_file || error "prepare remote file failed"
24491
24492         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24493         multiop_bg_pause $remote_file O_uc ||
24494                         error "mulitop failed for remote file"
24495         MULTIPID=$!
24496         $MULTIOP $DIR/$tfile Ouc
24497         kill -USR1 $MULTIPID
24498         wait $MULTIPID
24499 }
24500 run_test 310c "open-unlink remote file with multiple links"
24501
24502 #LU-4825
24503 test_311() {
24504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24505         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24506         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24507                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24508         remote_mds_nodsh && skip "remote MDS with nodsh"
24509
24510         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24511         local mdts=$(comma_list $(mdts_nodes))
24512
24513         mkdir -p $DIR/$tdir
24514         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24515         createmany -o $DIR/$tdir/$tfile. 1000
24516
24517         # statfs data is not real time, let's just calculate it
24518         old_iused=$((old_iused + 1000))
24519
24520         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24521                         osp.*OST0000*MDT0000.create_count")
24522         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24523                                 osp.*OST0000*MDT0000.max_create_count")
24524         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24525
24526         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24527         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24528         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24529
24530         unlinkmany $DIR/$tdir/$tfile. 1000
24531
24532         do_nodes $mdts "$LCTL set_param -n \
24533                         osp.*OST0000*.max_create_count=$max_count"
24534         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24535                 do_nodes $mdts "$LCTL set_param -n \
24536                                 osp.*OST0000*.create_count=$count"
24537         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24538                         grep "=0" && error "create_count is zero"
24539
24540         local new_iused
24541         for i in $(seq 120); do
24542                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24543                 # system may be too busy to destroy all objs in time, use
24544                 # a somewhat small value to not fail autotest
24545                 [ $((old_iused - new_iused)) -gt 400 ] && break
24546                 sleep 1
24547         done
24548
24549         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24550         [ $((old_iused - new_iused)) -gt 400 ] ||
24551                 error "objs not destroyed after unlink"
24552 }
24553 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24554
24555 zfs_oid_to_objid()
24556 {
24557         local ost=$1
24558         local objid=$2
24559
24560         local vdevdir=$(dirname $(facet_vdevice $ost))
24561         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24562         local zfs_zapid=$(do_facet $ost $cmd |
24563                           grep -w "/O/0/d$((objid%32))" -C 5 |
24564                           awk '/Object/{getline; print $1}')
24565         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24566                           awk "/$objid = /"'{printf $3}')
24567
24568         echo $zfs_objid
24569 }
24570
24571 zfs_object_blksz() {
24572         local ost=$1
24573         local objid=$2
24574
24575         local vdevdir=$(dirname $(facet_vdevice $ost))
24576         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24577         local blksz=$(do_facet $ost $cmd $objid |
24578                       awk '/dblk/{getline; printf $4}')
24579
24580         case "${blksz: -1}" in
24581                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24582                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24583                 *) ;;
24584         esac
24585
24586         echo $blksz
24587 }
24588
24589 test_312() { # LU-4856
24590         remote_ost_nodsh && skip "remote OST with nodsh"
24591         [ "$ost1_FSTYPE" = "zfs" ] ||
24592                 skip_env "the test only applies to zfs"
24593
24594         local max_blksz=$(do_facet ost1 \
24595                           $ZFS get -p recordsize $(facet_device ost1) |
24596                           awk '!/VALUE/{print $3}')
24597
24598         # to make life a little bit easier
24599         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24600         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24601
24602         local tf=$DIR/$tdir/$tfile
24603         touch $tf
24604         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24605
24606         # Get ZFS object id
24607         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24608         # block size change by sequential overwrite
24609         local bs
24610
24611         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24612                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24613
24614                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24615                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24616         done
24617         rm -f $tf
24618
24619         # block size change by sequential append write
24620         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24621         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24622         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24623         local count
24624
24625         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24626                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24627                         oflag=sync conv=notrunc
24628
24629                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24630                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24631                         error "blksz error, actual $blksz, " \
24632                                 "expected: 2 * $count * $PAGE_SIZE"
24633         done
24634         rm -f $tf
24635
24636         # random write
24637         touch $tf
24638         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24639         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24640
24641         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24642         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24643         [ $blksz -eq $PAGE_SIZE ] ||
24644                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24645
24646         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24647         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24648         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24649
24650         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24651         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24652         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24653 }
24654 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24655
24656 test_313() {
24657         remote_ost_nodsh && skip "remote OST with nodsh"
24658
24659         local file=$DIR/$tfile
24660
24661         rm -f $file
24662         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24663
24664         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24665         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24666         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24667                 error "write should failed"
24668         do_facet ost1 "$LCTL set_param fail_loc=0"
24669         rm -f $file
24670 }
24671 run_test 313 "io should fail after last_rcvd update fail"
24672
24673 test_314() {
24674         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24675
24676         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24677         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24678         rm -f $DIR/$tfile
24679         wait_delete_completed
24680         do_facet ost1 "$LCTL set_param fail_loc=0"
24681 }
24682 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24683
24684 test_315() { # LU-618
24685         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24686
24687         local file=$DIR/$tfile
24688         rm -f $file
24689
24690         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24691                 error "multiop file write failed"
24692         $MULTIOP $file oO_RDONLY:r4063232_c &
24693         PID=$!
24694
24695         sleep 2
24696
24697         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24698         kill -USR1 $PID
24699
24700         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24701         rm -f $file
24702 }
24703 run_test 315 "read should be accounted"
24704
24705 test_316() {
24706         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24707         large_xattr_enabled || skip "ea_inode feature disabled"
24708
24709         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24710         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24711         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24712         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24713
24714         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24715 }
24716 run_test 316 "lfs migrate of file with large_xattr enabled"
24717
24718 test_317() {
24719         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24720                 skip "Need MDS version at least 2.11.53"
24721         if [ "$ost1_FSTYPE" == "zfs" ]; then
24722                 skip "LU-10370: no implementation for ZFS"
24723         fi
24724
24725         local trunc_sz
24726         local grant_blk_size
24727
24728         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24729                         awk '/grant_block_size:/ { print $2; exit; }')
24730         #
24731         # Create File of size 5M. Truncate it to below size's and verify
24732         # blocks count.
24733         #
24734         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24735                 error "Create file $DIR/$tfile failed"
24736         stack_trap "rm -f $DIR/$tfile" EXIT
24737
24738         for trunc_sz in 2097152 4097 4000 509 0; do
24739                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24740                         error "truncate $tfile to $trunc_sz failed"
24741                 local sz=$(stat --format=%s $DIR/$tfile)
24742                 local blk=$(stat --format=%b $DIR/$tfile)
24743                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24744                                      grant_blk_size) * 8))
24745
24746                 if [[ $blk -ne $trunc_blk ]]; then
24747                         $(which stat) $DIR/$tfile
24748                         error "Expected Block $trunc_blk got $blk for $tfile"
24749                 fi
24750
24751                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24752                         error "Expected Size $trunc_sz got $sz for $tfile"
24753         done
24754
24755         #
24756         # sparse file test
24757         # Create file with a hole and write actual 65536 bytes which aligned
24758         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24759         #
24760         local bs=65536
24761         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24762                 error "Create file : $DIR/$tfile"
24763
24764         #
24765         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24766         # blocks. The block count must drop to 8.
24767         #
24768         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24769                 ((bs - grant_blk_size) + 1)))
24770         $TRUNCATE $DIR/$tfile $trunc_sz ||
24771                 error "truncate $tfile to $trunc_sz failed"
24772
24773         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24774         sz=$(stat --format=%s $DIR/$tfile)
24775         blk=$(stat --format=%b $DIR/$tfile)
24776
24777         if [[ $blk -ne $trunc_bsz ]]; then
24778                 $(which stat) $DIR/$tfile
24779                 error "Expected Block $trunc_bsz got $blk for $tfile"
24780         fi
24781
24782         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24783                 error "Expected Size $trunc_sz got $sz for $tfile"
24784 }
24785 run_test 317 "Verify blocks get correctly update after truncate"
24786
24787 test_318() {
24788         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24789         local old_max_active=$($LCTL get_param -n \
24790                             ${llite_name}.max_read_ahead_async_active \
24791                             2>/dev/null)
24792
24793         $LCTL set_param llite.*.max_read_ahead_async_active=256
24794         local max_active=$($LCTL get_param -n \
24795                            ${llite_name}.max_read_ahead_async_active \
24796                            2>/dev/null)
24797         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24798
24799         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24800                 error "set max_read_ahead_async_active should succeed"
24801
24802         $LCTL set_param llite.*.max_read_ahead_async_active=512
24803         max_active=$($LCTL get_param -n \
24804                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24805         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24806
24807         # restore @max_active
24808         [ $old_max_active -ne 0 ] && $LCTL set_param \
24809                 llite.*.max_read_ahead_async_active=$old_max_active
24810
24811         local old_threshold=$($LCTL get_param -n \
24812                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24813         local max_per_file_mb=$($LCTL get_param -n \
24814                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24815
24816         local invalid=$(($max_per_file_mb + 1))
24817         $LCTL set_param \
24818                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24819                         && error "set $invalid should fail"
24820
24821         local valid=$(($invalid - 1))
24822         $LCTL set_param \
24823                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24824                         error "set $valid should succeed"
24825         local threshold=$($LCTL get_param -n \
24826                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24827         [ $threshold -eq $valid ] || error \
24828                 "expect threshold $valid got $threshold"
24829         $LCTL set_param \
24830                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24831 }
24832 run_test 318 "Verify async readahead tunables"
24833
24834 test_319() {
24835         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24836
24837         local before=$(date +%s)
24838         local evict
24839         local mdir=$DIR/$tdir
24840         local file=$mdir/xxx
24841
24842         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24843         touch $file
24844
24845 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24846         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24847         $LFS migrate -m1 $mdir &
24848
24849         sleep 1
24850         dd if=$file of=/dev/null
24851         wait
24852         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24853           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24854
24855         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24856 }
24857 run_test 319 "lost lease lock on migrate error"
24858
24859 test_398a() { # LU-4198
24860         local ost1_imp=$(get_osc_import_name client ost1)
24861         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24862                          cut -d'.' -f2)
24863
24864         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24865         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24866
24867         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24868         # request a new lock on client
24869         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24870
24871         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24872         #local lock_count=$($LCTL get_param -n \
24873         #                  ldlm.namespaces.$imp_name.lru_size)
24874         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24875
24876         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24877
24878         # no lock cached, should use lockless DIO and not enqueue new lock
24879         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24880                 conv=notrunc ||
24881                 error "dio write failed"
24882         lock_count=$($LCTL get_param -n \
24883                      ldlm.namespaces.$imp_name.lru_size)
24884         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24885
24886         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24887
24888         # no lock cached, should use locked DIO append
24889         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24890                 conv=notrunc || error "DIO append failed"
24891         lock_count=$($LCTL get_param -n \
24892                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24893         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24894 }
24895 run_test 398a "direct IO should cancel lock otherwise lockless"
24896
24897 test_398b() { # LU-4198
24898         which fio || skip_env "no fio installed"
24899         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24900
24901         local size=48
24902         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24903
24904         local njobs=4
24905         # Single page, multiple pages, stripe size, 4*stripe size
24906         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24907                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24908                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24909                         --numjobs=$njobs --fallocate=none \
24910                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24911                         --filename=$DIR/$tfile &
24912                 bg_pid=$!
24913
24914                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24915                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24916                         --numjobs=$njobs --fallocate=none \
24917                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24918                         --filename=$DIR/$tfile || true
24919                 wait $bg_pid
24920         done
24921
24922         evict=$(do_facet client $LCTL get_param \
24923                 osc.$FSNAME-OST*-osc-*/state |
24924             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24925
24926         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24927                 (do_facet client $LCTL get_param \
24928                         osc.$FSNAME-OST*-osc-*/state;
24929                     error "eviction happened: $evict before:$before")
24930
24931         rm -f $DIR/$tfile
24932 }
24933 run_test 398b "DIO and buffer IO race"
24934
24935 test_398c() { # LU-4198
24936         local ost1_imp=$(get_osc_import_name client ost1)
24937         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24938                          cut -d'.' -f2)
24939
24940         which fio || skip_env "no fio installed"
24941
24942         saved_debug=$($LCTL get_param -n debug)
24943         $LCTL set_param debug=0
24944
24945         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24946         ((size /= 1024)) # by megabytes
24947         ((size /= 2)) # write half of the OST at most
24948         [ $size -gt 40 ] && size=40 #reduce test time anyway
24949
24950         $LFS setstripe -c 1 $DIR/$tfile
24951
24952         # it seems like ldiskfs reserves more space than necessary if the
24953         # writing blocks are not mapped, so it extends the file firstly
24954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24955         cancel_lru_locks osc
24956
24957         # clear and verify rpc_stats later
24958         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24959
24960         local njobs=4
24961         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24962         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24963                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24964                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24965                 --filename=$DIR/$tfile
24966         [ $? -eq 0 ] || error "fio write error"
24967
24968         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24969                 error "Locks were requested while doing AIO"
24970
24971         # get the percentage of 1-page I/O
24972         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24973                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24974                 awk '{print $7}')
24975         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24976
24977         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24978         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24979                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24980                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24981                 --filename=$DIR/$tfile
24982         [ $? -eq 0 ] || error "fio mixed read write error"
24983
24984         echo "AIO with large block size ${size}M"
24985         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24986                 --numjobs=1 --fallocate=none --ioengine=libaio \
24987                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24988                 --filename=$DIR/$tfile
24989         [ $? -eq 0 ] || error "fio large block size failed"
24990
24991         rm -f $DIR/$tfile
24992         $LCTL set_param debug="$saved_debug"
24993 }
24994 run_test 398c "run fio to test AIO"
24995
24996 test_398d() { #  LU-13846
24997         which aiocp || skip_env "no aiocp installed"
24998         local aio_file=$DIR/$tfile.aio
24999
25000         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25001
25002         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25003         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25004         stack_trap "rm -f $DIR/$tfile $aio_file"
25005
25006         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25007
25008         # make sure we don't crash and fail properly
25009         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25010                 error "aio not aligned with PAGE SIZE should fail"
25011
25012         rm -f $DIR/$tfile $aio_file
25013 }
25014 run_test 398d "run aiocp to verify block size > stripe size"
25015
25016 test_398e() {
25017         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25018         touch $DIR/$tfile.new
25019         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25020 }
25021 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25022
25023 test_398f() { #  LU-14687
25024         which aiocp || skip_env "no aiocp installed"
25025         local aio_file=$DIR/$tfile.aio
25026
25027         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25028
25029         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25030         stack_trap "rm -f $DIR/$tfile $aio_file"
25031
25032         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25033         $LCTL set_param fail_loc=0x1418
25034         # make sure we don't crash and fail properly
25035         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25036                 error "aio with page allocation failure succeeded"
25037         $LCTL set_param fail_loc=0
25038         diff $DIR/$tfile $aio_file
25039         [[ $? != 0 ]] || error "no diff after failed aiocp"
25040 }
25041 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25042
25043 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25044 # stripe and i/o size must be > stripe size
25045 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25046 # single RPC in flight.  This test shows async DIO submission is working by
25047 # showing multiple RPCs in flight.
25048 test_398g() { #  LU-13798
25049         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25050
25051         # We need to do some i/o first to acquire enough grant to put our RPCs
25052         # in flight; otherwise a new connection may not have enough grant
25053         # available
25054         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25055                 error "parallel dio failed"
25056         stack_trap "rm -f $DIR/$tfile"
25057
25058         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25059         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25060         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25061         stack_trap "$LCTL set_param -n $pages_per_rpc"
25062
25063         # Recreate file so it's empty
25064         rm -f $DIR/$tfile
25065         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25066         #Pause rpc completion to guarantee we see multiple rpcs in flight
25067         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25068         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25069         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25070
25071         # Clear rpc stats
25072         $LCTL set_param osc.*.rpc_stats=c
25073
25074         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25075                 error "parallel dio failed"
25076         stack_trap "rm -f $DIR/$tfile"
25077
25078         $LCTL get_param osc.*-OST0000-*.rpc_stats
25079         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25080                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25081                 grep "8:" | awk '{print $8}')
25082         # We look at the "8 rpcs in flight" field, and verify A) it is present
25083         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25084         # as expected for an 8M DIO to a file with 1M stripes.
25085         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25086
25087         # Verify turning off parallel dio works as expected
25088         # Clear rpc stats
25089         $LCTL set_param osc.*.rpc_stats=c
25090         $LCTL set_param llite.*.parallel_dio=0
25091         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25092
25093         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25094                 error "dio with parallel dio disabled failed"
25095
25096         # Ideally, we would see only one RPC in flight here, but there is an
25097         # unavoidable race between i/o completion and RPC in flight counting,
25098         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25099         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25100         # So instead we just verify it's always < 8.
25101         $LCTL get_param osc.*-OST0000-*.rpc_stats
25102         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25103                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25104                 grep '^$' -B1 | grep . | awk '{print $1}')
25105         [ $ret != "8:" ] ||
25106                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25107 }
25108 run_test 398g "verify parallel dio async RPC submission"
25109
25110 test_398h() { #  LU-13798
25111         local dio_file=$DIR/$tfile.dio
25112
25113         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25114
25115         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25116         stack_trap "rm -f $DIR/$tfile $dio_file"
25117
25118         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25119                 error "parallel dio failed"
25120         diff $DIR/$tfile $dio_file
25121         [[ $? == 0 ]] || error "file diff after aiocp"
25122 }
25123 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25124
25125 test_398i() { #  LU-13798
25126         local dio_file=$DIR/$tfile.dio
25127
25128         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25129
25130         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25131         stack_trap "rm -f $DIR/$tfile $dio_file"
25132
25133         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25134         $LCTL set_param fail_loc=0x1418
25135         # make sure we don't crash and fail properly
25136         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25137                 error "parallel dio page allocation failure succeeded"
25138         diff $DIR/$tfile $dio_file
25139         [[ $? != 0 ]] || error "no diff after failed aiocp"
25140 }
25141 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25142
25143 test_398j() { #  LU-13798
25144         # Stripe size > RPC size but less than i/o size tests split across
25145         # stripes and RPCs for individual i/o op
25146         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25147
25148         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25149         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25150         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25151         stack_trap "$LCTL set_param -n $pages_per_rpc"
25152
25153         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25154                 error "parallel dio write failed"
25155         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25156
25157         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25158                 error "parallel dio read failed"
25159         diff $DIR/$tfile $DIR/$tfile.2
25160         [[ $? == 0 ]] || error "file diff after parallel dio read"
25161 }
25162 run_test 398j "test parallel dio where stripe size > rpc_size"
25163
25164 test_398k() { #  LU-13798
25165         wait_delete_completed
25166         wait_mds_ost_sync
25167
25168         # 4 stripe file; we will cause out of space on OST0
25169         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25170
25171         # Fill OST0 (if it's not too large)
25172         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25173                    head -n1)
25174         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25175                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25176         fi
25177         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25178         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25179                 error "dd should fill OST0"
25180         stack_trap "rm -f $DIR/$tfile.1"
25181
25182         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25183         err=$?
25184
25185         ls -la $DIR/$tfile
25186         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25187                 error "file is not 0 bytes in size"
25188
25189         # dd above should not succeed, but don't error until here so we can
25190         # get debug info above
25191         [[ $err != 0 ]] ||
25192                 error "parallel dio write with enospc succeeded"
25193         stack_trap "rm -f $DIR/$tfile"
25194 }
25195 run_test 398k "test enospc on first stripe"
25196
25197 test_398l() { #  LU-13798
25198         wait_delete_completed
25199         wait_mds_ost_sync
25200
25201         # 4 stripe file; we will cause out of space on OST0
25202         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25203         # happens on the second i/o chunk we issue
25204         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25205
25206         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25207         stack_trap "rm -f $DIR/$tfile"
25208
25209         # Fill OST0 (if it's not too large)
25210         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25211                    head -n1)
25212         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25213                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25214         fi
25215         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25216         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25217                 error "dd should fill OST0"
25218         stack_trap "rm -f $DIR/$tfile.1"
25219
25220         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25221         err=$?
25222         stack_trap "rm -f $DIR/$tfile.2"
25223
25224         # Check that short write completed as expected
25225         ls -la $DIR/$tfile.2
25226         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25227                 error "file is not 1M in size"
25228
25229         # dd above should not succeed, but don't error until here so we can
25230         # get debug info above
25231         [[ $err != 0 ]] ||
25232                 error "parallel dio write with enospc succeeded"
25233
25234         # Truncate source file to same length as output file and diff them
25235         $TRUNCATE $DIR/$tfile 1048576
25236         diff $DIR/$tfile $DIR/$tfile.2
25237         [[ $? == 0 ]] || error "data incorrect after short write"
25238 }
25239 run_test 398l "test enospc on intermediate stripe/RPC"
25240
25241 test_398m() { #  LU-13798
25242         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25243
25244         # Set up failure on OST0, the first stripe:
25245         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25246         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25247         # So this fail_val specifies OST0
25248         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25249         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25250
25251         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25252                 error "parallel dio write with failure on first stripe succeeded"
25253         stack_trap "rm -f $DIR/$tfile"
25254         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25255
25256         # Place data in file for read
25257         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25258                 error "parallel dio write failed"
25259
25260         # Fail read on OST0, first stripe
25261         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25262         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25263         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25264                 error "parallel dio read with error on first stripe succeeded"
25265         rm -f $DIR/$tfile.2
25266         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25267
25268         # Switch to testing on OST1, second stripe
25269         # Clear file contents, maintain striping
25270         echo > $DIR/$tfile
25271         # Set up failure on OST1, second stripe:
25272         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25273         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25274
25275         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25276                 error "parallel dio write with failure on first stripe succeeded"
25277         stack_trap "rm -f $DIR/$tfile"
25278         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25279
25280         # Place data in file for read
25281         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25282                 error "parallel dio write failed"
25283
25284         # Fail read on OST1, second stripe
25285         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25286         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25287         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25288                 error "parallel dio read with error on first stripe succeeded"
25289         rm -f $DIR/$tfile.2
25290         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25291 }
25292 run_test 398m "test RPC failures with parallel dio"
25293
25294 # Parallel submission of DIO should not cause problems for append, but it's
25295 # important to verify.
25296 test_398n() { #  LU-13798
25297         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25298
25299         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25300                 error "dd to create source file failed"
25301         stack_trap "rm -f $DIR/$tfile"
25302
25303         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25304                 error "parallel dio write with failure on second stripe succeeded"
25305         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25306         diff $DIR/$tfile $DIR/$tfile.1
25307         [[ $? == 0 ]] || error "data incorrect after append"
25308
25309 }
25310 run_test 398n "test append with parallel DIO"
25311
25312 test_398o() {
25313         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25314 }
25315 run_test 398o "right kms with DIO"
25316
25317 test_fake_rw() {
25318         local read_write=$1
25319         if [ "$read_write" = "write" ]; then
25320                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25321         elif [ "$read_write" = "read" ]; then
25322                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25323         else
25324                 error "argument error"
25325         fi
25326
25327         # turn off debug for performance testing
25328         local saved_debug=$($LCTL get_param -n debug)
25329         $LCTL set_param debug=0
25330
25331         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25332
25333         # get ost1 size - $FSNAME-OST0000
25334         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25335         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25336         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25337
25338         if [ "$read_write" = "read" ]; then
25339                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25340         fi
25341
25342         local start_time=$(date +%s.%N)
25343         $dd_cmd bs=1M count=$blocks oflag=sync ||
25344                 error "real dd $read_write error"
25345         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25346
25347         if [ "$read_write" = "write" ]; then
25348                 rm -f $DIR/$tfile
25349         fi
25350
25351         # define OBD_FAIL_OST_FAKE_RW           0x238
25352         do_facet ost1 $LCTL set_param fail_loc=0x238
25353
25354         local start_time=$(date +%s.%N)
25355         $dd_cmd bs=1M count=$blocks oflag=sync ||
25356                 error "fake dd $read_write error"
25357         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25358
25359         if [ "$read_write" = "write" ]; then
25360                 # verify file size
25361                 cancel_lru_locks osc
25362                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25363                         error "$tfile size not $blocks MB"
25364         fi
25365         do_facet ost1 $LCTL set_param fail_loc=0
25366
25367         echo "fake $read_write $duration_fake vs. normal $read_write" \
25368                 "$duration in seconds"
25369         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25370                 error_not_in_vm "fake write is slower"
25371
25372         $LCTL set_param -n debug="$saved_debug"
25373         rm -f $DIR/$tfile
25374 }
25375 test_399a() { # LU-7655 for OST fake write
25376         remote_ost_nodsh && skip "remote OST with nodsh"
25377
25378         test_fake_rw write
25379 }
25380 run_test 399a "fake write should not be slower than normal write"
25381
25382 test_399b() { # LU-8726 for OST fake read
25383         remote_ost_nodsh && skip "remote OST with nodsh"
25384         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25385                 skip_env "ldiskfs only test"
25386         fi
25387
25388         test_fake_rw read
25389 }
25390 run_test 399b "fake read should not be slower than normal read"
25391
25392 test_400a() { # LU-1606, was conf-sanity test_74
25393         if ! which $CC > /dev/null 2>&1; then
25394                 skip_env "$CC is not installed"
25395         fi
25396
25397         local extra_flags=''
25398         local out=$TMP/$tfile
25399         local prefix=/usr/include/lustre
25400         local prog
25401
25402         # Oleg removes c files in his test rig so test if any c files exist
25403         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25404                 skip_env "Needed c test files are missing"
25405
25406         if ! [[ -d $prefix ]]; then
25407                 # Assume we're running in tree and fixup the include path.
25408                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25409                 extra_flags+=" -L$LUSTRE/utils/.lib"
25410         fi
25411
25412         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25413                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25414                         error "client api broken"
25415         done
25416         rm -f $out
25417 }
25418 run_test 400a "Lustre client api program can compile and link"
25419
25420 test_400b() { # LU-1606, LU-5011
25421         local header
25422         local out=$TMP/$tfile
25423         local prefix=/usr/include/linux/lustre
25424
25425         # We use a hard coded prefix so that this test will not fail
25426         # when run in tree. There are headers in lustre/include/lustre/
25427         # that are not packaged (like lustre_idl.h) and have more
25428         # complicated include dependencies (like config.h and lnet/types.h).
25429         # Since this test about correct packaging we just skip them when
25430         # they don't exist (see below) rather than try to fixup cppflags.
25431
25432         if ! which $CC > /dev/null 2>&1; then
25433                 skip_env "$CC is not installed"
25434         fi
25435
25436         for header in $prefix/*.h; do
25437                 if ! [[ -f "$header" ]]; then
25438                         continue
25439                 fi
25440
25441                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25442                         continue # lustre_ioctl.h is internal header
25443                 fi
25444
25445                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25446                         error "cannot compile '$header'"
25447         done
25448         rm -f $out
25449 }
25450 run_test 400b "packaged headers can be compiled"
25451
25452 test_401a() { #LU-7437
25453         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25454         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25455
25456         #count the number of parameters by "list_param -R"
25457         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25458         #count the number of parameters by listing proc files
25459         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25460         echo "proc_dirs='$proc_dirs'"
25461         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25462         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25463                       sort -u | wc -l)
25464
25465         [ $params -eq $procs ] ||
25466                 error "found $params parameters vs. $procs proc files"
25467
25468         # test the list_param -D option only returns directories
25469         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25470         #count the number of parameters by listing proc directories
25471         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25472                 sort -u | wc -l)
25473
25474         [ $params -eq $procs ] ||
25475                 error "found $params parameters vs. $procs proc files"
25476 }
25477 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25478
25479 test_401b() {
25480         # jobid_var may not allow arbitrary values, so use jobid_name
25481         # if available
25482         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25483                 local testname=jobid_name tmp='testing%p'
25484         else
25485                 local testname=jobid_var tmp=testing
25486         fi
25487
25488         local save=$($LCTL get_param -n $testname)
25489
25490         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25491                 error "no error returned when setting bad parameters"
25492
25493         local jobid_new=$($LCTL get_param -n foe $testname baz)
25494         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25495
25496         $LCTL set_param -n fog=bam $testname=$save bat=fog
25497         local jobid_old=$($LCTL get_param -n foe $testname bag)
25498         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25499 }
25500 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25501
25502 test_401c() {
25503         # jobid_var may not allow arbitrary values, so use jobid_name
25504         # if available
25505         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25506                 local testname=jobid_name
25507         else
25508                 local testname=jobid_var
25509         fi
25510
25511         local jobid_var_old=$($LCTL get_param -n $testname)
25512         local jobid_var_new
25513
25514         $LCTL set_param $testname= &&
25515                 error "no error returned for 'set_param a='"
25516
25517         jobid_var_new=$($LCTL get_param -n $testname)
25518         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25519                 error "$testname was changed by setting without value"
25520
25521         $LCTL set_param $testname &&
25522                 error "no error returned for 'set_param a'"
25523
25524         jobid_var_new=$($LCTL get_param -n $testname)
25525         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25526                 error "$testname was changed by setting without value"
25527 }
25528 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25529
25530 test_401d() {
25531         # jobid_var may not allow arbitrary values, so use jobid_name
25532         # if available
25533         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25534                 local testname=jobid_name new_value='foo=bar%p'
25535         else
25536                 local testname=jobid_var new_valuie=foo=bar
25537         fi
25538
25539         local jobid_var_old=$($LCTL get_param -n $testname)
25540         local jobid_var_new
25541
25542         $LCTL set_param $testname=$new_value ||
25543                 error "'set_param a=b' did not accept a value containing '='"
25544
25545         jobid_var_new=$($LCTL get_param -n $testname)
25546         [[ "$jobid_var_new" == "$new_value" ]] ||
25547                 error "'set_param a=b' failed on a value containing '='"
25548
25549         # Reset the $testname to test the other format
25550         $LCTL set_param $testname=$jobid_var_old
25551         jobid_var_new=$($LCTL get_param -n $testname)
25552         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25553                 error "failed to reset $testname"
25554
25555         $LCTL set_param $testname $new_value ||
25556                 error "'set_param a b' did not accept a value containing '='"
25557
25558         jobid_var_new=$($LCTL get_param -n $testname)
25559         [[ "$jobid_var_new" == "$new_value" ]] ||
25560                 error "'set_param a b' failed on a value containing '='"
25561
25562         $LCTL set_param $testname $jobid_var_old
25563         jobid_var_new=$($LCTL get_param -n $testname)
25564         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25565                 error "failed to reset $testname"
25566 }
25567 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25568
25569 test_401e() { # LU-14779
25570         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25571                 error "lctl list_param MGC* failed"
25572         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25573         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25574                 error "lctl get_param lru_size failed"
25575 }
25576 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25577
25578 test_402() {
25579         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25580         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25581                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25582         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25583                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25584                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25585         remote_mds_nodsh && skip "remote MDS with nodsh"
25586
25587         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25588 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25589         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25590         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25591                 echo "Touch failed - OK"
25592 }
25593 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25594
25595 test_403() {
25596         local file1=$DIR/$tfile.1
25597         local file2=$DIR/$tfile.2
25598         local tfile=$TMP/$tfile
25599
25600         rm -f $file1 $file2 $tfile
25601
25602         touch $file1
25603         ln $file1 $file2
25604
25605         # 30 sec OBD_TIMEOUT in ll_getattr()
25606         # right before populating st_nlink
25607         $LCTL set_param fail_loc=0x80001409
25608         stat -c %h $file1 > $tfile &
25609
25610         # create an alias, drop all locks and reclaim the dentry
25611         < $file2
25612         cancel_lru_locks mdc
25613         cancel_lru_locks osc
25614         sysctl -w vm.drop_caches=2
25615
25616         wait
25617
25618         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25619
25620         rm -f $tfile $file1 $file2
25621 }
25622 run_test 403 "i_nlink should not drop to zero due to aliasing"
25623
25624 test_404() { # LU-6601
25625         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25626                 skip "Need server version newer than 2.8.52"
25627         remote_mds_nodsh && skip "remote MDS with nodsh"
25628
25629         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25630                 awk '/osp .*-osc-MDT/ { print $4}')
25631
25632         local osp
25633         for osp in $mosps; do
25634                 echo "Deactivate: " $osp
25635                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25636                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25637                         awk -vp=$osp '$4 == p { print $2 }')
25638                 [ $stat = IN ] || {
25639                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25640                         error "deactivate error"
25641                 }
25642                 echo "Activate: " $osp
25643                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25644                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25645                         awk -vp=$osp '$4 == p { print $2 }')
25646                 [ $stat = UP ] || {
25647                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25648                         error "activate error"
25649                 }
25650         done
25651 }
25652 run_test 404 "validate manual {de}activated works properly for OSPs"
25653
25654 test_405() {
25655         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25656         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25657                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25658                         skip "Layout swap lock is not supported"
25659
25660         check_swap_layouts_support
25661         check_swap_layout_no_dom $DIR
25662
25663         test_mkdir $DIR/$tdir
25664         swap_lock_test -d $DIR/$tdir ||
25665                 error "One layout swap locked test failed"
25666 }
25667 run_test 405 "Various layout swap lock tests"
25668
25669 test_406() {
25670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25671         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25672         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25674         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25675                 skip "Need MDS version at least 2.8.50"
25676
25677         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25678         local test_pool=$TESTNAME
25679
25680         pool_add $test_pool || error "pool_add failed"
25681         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25682                 error "pool_add_targets failed"
25683
25684         save_layout_restore_at_exit $MOUNT
25685
25686         # parent set default stripe count only, child will stripe from both
25687         # parent and fs default
25688         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25689                 error "setstripe $MOUNT failed"
25690         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25691         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25692         for i in $(seq 10); do
25693                 local f=$DIR/$tdir/$tfile.$i
25694                 touch $f || error "touch failed"
25695                 local count=$($LFS getstripe -c $f)
25696                 [ $count -eq $OSTCOUNT ] ||
25697                         error "$f stripe count $count != $OSTCOUNT"
25698                 local offset=$($LFS getstripe -i $f)
25699                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25700                 local size=$($LFS getstripe -S $f)
25701                 [ $size -eq $((def_stripe_size * 2)) ] ||
25702                         error "$f stripe size $size != $((def_stripe_size * 2))"
25703                 local pool=$($LFS getstripe -p $f)
25704                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25705         done
25706
25707         # change fs default striping, delete parent default striping, now child
25708         # will stripe from new fs default striping only
25709         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25710                 error "change $MOUNT default stripe failed"
25711         $LFS setstripe -c 0 $DIR/$tdir ||
25712                 error "delete $tdir default stripe failed"
25713         for i in $(seq 11 20); do
25714                 local f=$DIR/$tdir/$tfile.$i
25715                 touch $f || error "touch $f failed"
25716                 local count=$($LFS getstripe -c $f)
25717                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25718                 local offset=$($LFS getstripe -i $f)
25719                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25720                 local size=$($LFS getstripe -S $f)
25721                 [ $size -eq $def_stripe_size ] ||
25722                         error "$f stripe size $size != $def_stripe_size"
25723                 local pool=$($LFS getstripe -p $f)
25724                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25725         done
25726
25727         unlinkmany $DIR/$tdir/$tfile. 1 20
25728
25729         local f=$DIR/$tdir/$tfile
25730         pool_remove_all_targets $test_pool $f
25731         pool_remove $test_pool $f
25732 }
25733 run_test 406 "DNE support fs default striping"
25734
25735 test_407() {
25736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25737         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25738                 skip "Need MDS version at least 2.8.55"
25739         remote_mds_nodsh && skip "remote MDS with nodsh"
25740
25741         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25742                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25743         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25744                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25745         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25746
25747         #define OBD_FAIL_DT_TXN_STOP    0x2019
25748         for idx in $(seq $MDSCOUNT); do
25749                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25750         done
25751         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25752         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25753                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25754         true
25755 }
25756 run_test 407 "transaction fail should cause operation fail"
25757
25758 test_408() {
25759         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25760
25761         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25762         lctl set_param fail_loc=0x8000040a
25763         # let ll_prepare_partial_page() fail
25764         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25765
25766         rm -f $DIR/$tfile
25767
25768         # create at least 100 unused inodes so that
25769         # shrink_icache_memory(0) should not return 0
25770         touch $DIR/$tfile-{0..100}
25771         rm -f $DIR/$tfile-{0..100}
25772         sync
25773
25774         echo 2 > /proc/sys/vm/drop_caches
25775 }
25776 run_test 408 "drop_caches should not hang due to page leaks"
25777
25778 test_409()
25779 {
25780         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25781
25782         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25783         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25784         touch $DIR/$tdir/guard || error "(2) Fail to create"
25785
25786         local PREFIX=$(str_repeat 'A' 128)
25787         echo "Create 1K hard links start at $(date)"
25788         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25789                 error "(3) Fail to hard link"
25790
25791         echo "Links count should be right although linkEA overflow"
25792         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25793         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25794         [ $linkcount -eq 1001 ] ||
25795                 error "(5) Unexpected hard links count: $linkcount"
25796
25797         echo "List all links start at $(date)"
25798         ls -l $DIR/$tdir/foo > /dev/null ||
25799                 error "(6) Fail to list $DIR/$tdir/foo"
25800
25801         echo "Unlink hard links start at $(date)"
25802         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25803                 error "(7) Fail to unlink"
25804         echo "Unlink hard links finished at $(date)"
25805 }
25806 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25807
25808 test_410()
25809 {
25810         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25811                 skip "Need client version at least 2.9.59"
25812         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25813                 skip "Need MODULES build"
25814
25815         # Create a file, and stat it from the kernel
25816         local testfile=$DIR/$tfile
25817         touch $testfile
25818
25819         local run_id=$RANDOM
25820         local my_ino=$(stat --format "%i" $testfile)
25821
25822         # Try to insert the module. This will always fail as the
25823         # module is designed to not be inserted.
25824         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25825             &> /dev/null
25826
25827         # Anything but success is a test failure
25828         dmesg | grep -q \
25829             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25830             error "no inode match"
25831 }
25832 run_test 410 "Test inode number returned from kernel thread"
25833
25834 cleanup_test411_cgroup() {
25835         trap 0
25836         rmdir "$1"
25837 }
25838
25839 test_411() {
25840         local cg_basedir=/sys/fs/cgroup/memory
25841         # LU-9966
25842         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25843                 skip "no setup for cgroup"
25844
25845         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25846                 error "test file creation failed"
25847         cancel_lru_locks osc
25848
25849         # Create a very small memory cgroup to force a slab allocation error
25850         local cgdir=$cg_basedir/osc_slab_alloc
25851         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25852         trap "cleanup_test411_cgroup $cgdir" EXIT
25853         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25854         echo 1M > $cgdir/memory.limit_in_bytes
25855
25856         # Should not LBUG, just be killed by oom-killer
25857         # dd will return 0 even allocation failure in some environment.
25858         # So don't check return value
25859         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25860         cleanup_test411_cgroup $cgdir
25861
25862         return 0
25863 }
25864 run_test 411 "Slab allocation error with cgroup does not LBUG"
25865
25866 test_412() {
25867         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25868         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25869                 skip "Need server version at least 2.10.55"
25870
25871         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25872                 error "mkdir failed"
25873         $LFS getdirstripe $DIR/$tdir
25874         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25875         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25876                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25877         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25878         [ $stripe_count -eq 2 ] ||
25879                 error "expect 2 get $stripe_count"
25880
25881         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25882
25883         local index
25884         local index2
25885
25886         # subdirs should be on the same MDT as parent
25887         for i in $(seq 0 $((MDSCOUNT - 1))); do
25888                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25889                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25890                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25891                 (( index == i )) || error "mdt$i/sub on MDT$index"
25892         done
25893
25894         # stripe offset -1, ditto
25895         for i in {1..10}; do
25896                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25897                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25898                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25899                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25900                 (( index == index2 )) ||
25901                         error "qos$i on MDT$index, sub on MDT$index2"
25902         done
25903
25904         local testdir=$DIR/$tdir/inherit
25905
25906         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25907         # inherit 2 levels
25908         for i in 1 2; do
25909                 testdir=$testdir/s$i
25910                 mkdir $testdir || error "mkdir $testdir failed"
25911                 index=$($LFS getstripe -m $testdir)
25912                 (( index == 1 )) ||
25913                         error "$testdir on MDT$index"
25914         done
25915
25916         # not inherit any more
25917         testdir=$testdir/s3
25918         mkdir $testdir || error "mkdir $testdir failed"
25919         getfattr -d -m dmv $testdir | grep dmv &&
25920                 error "default LMV set on $testdir" || true
25921 }
25922 run_test 412 "mkdir on specific MDTs"
25923
25924 TEST413_COUNT=${TEST413_COUNT:-200}
25925 generate_uneven_mdts() {
25926         local threshold=$1
25927         local lmv_qos_maxage
25928         local lod_qos_maxage
25929         local ffree
25930         local bavail
25931         local max
25932         local min
25933         local max_index
25934         local min_index
25935         local tmp
25936         local i
25937
25938         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25939         $LCTL set_param lmv.*.qos_maxage=1
25940         stack_trap "$LCTL set_param \
25941                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25942         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25943                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25944         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25945                 lod.*.mdt_qos_maxage=1
25946         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25947                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25948
25949         echo
25950         echo "Check for uneven MDTs: "
25951
25952         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25953         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25954         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25955
25956         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25957         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25958         max_index=0
25959         min_index=0
25960         for ((i = 1; i < ${#ffree[@]}; i++)); do
25961                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25962                 if [ $tmp -gt $max ]; then
25963                         max=$tmp
25964                         max_index=$i
25965                 fi
25966                 if [ $tmp -lt $min ]; then
25967                         min=$tmp
25968                         min_index=$i
25969                 fi
25970         done
25971
25972         (( ${ffree[min_index]} > 0 )) ||
25973                 skip "no free files in MDT$min_index"
25974         (( ${ffree[min_index]} < 10000000 )) ||
25975                 skip "too many free files in MDT$min_index"
25976
25977         # Check if we need to generate uneven MDTs
25978         local diff=$(((max - min) * 100 / min))
25979         local testdir=$DIR/$tdir-fillmdt
25980         local start
25981
25982         i=0
25983         while (( diff < threshold )); do
25984                 mkdir -p $testdir
25985                 # generate uneven MDTs, create till $threshold% diff
25986                 echo -n "weight diff=$diff% must be > $threshold% ..."
25987                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25988                 testdir=$DIR/$tdir-fillmdt/$i
25989                 [ -d $testdir ] && continue
25990                 $LFS mkdir -i $min_index $testdir ||
25991                         error "mkdir $testdir failed"
25992                 $LFS setstripe -E 1M -L mdt $testdir ||
25993                         error "setstripe $testdir failed"
25994                 start=$SECONDS
25995                 for ((F=0; F < TEST413_COUNT; F++)); do
25996                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25997                                 /dev/null 2>&1 || error "dd $F failed"
25998                 done
25999                 sync; sleep 1; sync
26000
26001                 # wait for QOS to update
26002                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26003
26004                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26005                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26006                 max=$(((${ffree[max_index]} >> 8) *
26007                         (${bavail[max_index]} * bsize >> 16)))
26008                 min=$(((${ffree[min_index]} >> 8) *
26009                         (${bavail[min_index]} * bsize >> 16)))
26010                 diff=$(((max - min) * 100 / min))
26011                 i=$((i + 1))
26012         done
26013
26014         echo "MDT filesfree available: ${ffree[*]}"
26015         echo "MDT blocks available: ${bavail[*]}"
26016         echo "weight diff=$diff%"
26017 }
26018
26019 test_qos_mkdir() {
26020         local mkdir_cmd=$1
26021         local stripe_count=$2
26022         local mdts=$(comma_list $(mdts_nodes))
26023
26024         local testdir
26025         local lmv_qos_prio_free
26026         local lmv_qos_threshold_rr
26027         local lmv_qos_maxage
26028         local lod_qos_prio_free
26029         local lod_qos_threshold_rr
26030         local lod_qos_maxage
26031         local count
26032         local i
26033
26034         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26035         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26036         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26037                 head -n1)
26038         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26039         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26040         stack_trap "$LCTL set_param \
26041                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26042         stack_trap "$LCTL set_param \
26043                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26044         stack_trap "$LCTL set_param \
26045                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26046
26047         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26048                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26049         lod_qos_prio_free=${lod_qos_prio_free%%%}
26050         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26051                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26052         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26053         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26054                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26055         stack_trap "do_nodes $mdts $LCTL set_param \
26056                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26057         stack_trap "do_nodes $mdts $LCTL set_param \
26058                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26059         stack_trap "do_nodes $mdts $LCTL set_param \
26060                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26061
26062         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26063         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26064
26065         testdir=$DIR/$tdir-s$stripe_count/rr
26066
26067         local stripe_index=$($LFS getstripe -m $testdir)
26068         local test_mkdir_rr=true
26069
26070         getfattr -d -m dmv -e hex $testdir | grep dmv
26071         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26072                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26073                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26074                         test_mkdir_rr=false
26075         fi
26076
26077         echo
26078         $test_mkdir_rr &&
26079                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26080                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26081
26082         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26083         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26084                 eval $mkdir_cmd $testdir/subdir$i ||
26085                         error "$mkdir_cmd subdir$i failed"
26086         done
26087
26088         for (( i = 0; i < $MDSCOUNT; i++ )); do
26089                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26090                 echo "$count directories created on MDT$i"
26091                 if $test_mkdir_rr; then
26092                         (( $count == 100 )) ||
26093                                 error "subdirs are not evenly distributed"
26094                 elif (( $i == $stripe_index )); then
26095                         (( $count == 100 * MDSCOUNT )) ||
26096                                 error "$count subdirs created on MDT$i"
26097                 else
26098                         (( $count == 0 )) ||
26099                                 error "$count subdirs created on MDT$i"
26100                 fi
26101
26102                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26103                         count=$($LFS getdirstripe $testdir/* |
26104                                 grep -c -P "^\s+$i\t")
26105                         echo "$count stripes created on MDT$i"
26106                         # deviation should < 5% of average
26107                         (( $count >= 95 * stripe_count &&
26108                            $count <= 105 * stripe_count)) ||
26109                                 error "stripes are not evenly distributed"
26110                 fi
26111         done
26112
26113         echo
26114         echo "Check for uneven MDTs: "
26115
26116         local ffree
26117         local bavail
26118         local max
26119         local min
26120         local max_index
26121         local min_index
26122         local tmp
26123
26124         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26125         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26126         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26127
26128         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26129         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26130         max_index=0
26131         min_index=0
26132         for ((i = 1; i < ${#ffree[@]}; i++)); do
26133                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26134                 if [ $tmp -gt $max ]; then
26135                         max=$tmp
26136                         max_index=$i
26137                 fi
26138                 if [ $tmp -lt $min ]; then
26139                         min=$tmp
26140                         min_index=$i
26141                 fi
26142         done
26143
26144         (( ${ffree[min_index]} > 0 )) ||
26145                 skip "no free files in MDT$min_index"
26146         (( ${ffree[min_index]} < 10000000 )) ||
26147                 skip "too many free files in MDT$min_index"
26148
26149         echo "MDT filesfree available: ${ffree[*]}"
26150         echo "MDT blocks available: ${bavail[*]}"
26151         echo "weight diff=$(((max - min) * 100 / min))%"
26152         echo
26153         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26154
26155         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26156         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26157         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26158         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26159         # decrease statfs age, so that it can be updated in time
26160         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26161         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26162
26163         sleep 1
26164
26165         testdir=$DIR/$tdir-s$stripe_count/qos
26166         local num=200
26167
26168         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26169         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26170                 eval $mkdir_cmd $testdir/subdir$i ||
26171                         error "$mkdir_cmd subdir$i failed"
26172         done
26173
26174         max=0
26175         for (( i = 0; i < $MDSCOUNT; i++ )); do
26176                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26177                 (( count > max )) && max=$count
26178                 echo "$count directories created on MDT$i"
26179         done
26180
26181         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26182
26183         # D-value should > 10% of averge
26184         (( max - min > num / 10 )) ||
26185                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26186
26187         # ditto for stripes
26188         if (( stripe_count > 1 )); then
26189                 max=0
26190                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26191                         count=$($LFS getdirstripe $testdir/* |
26192                                 grep -c -P "^\s+$i\t")
26193                         (( count > max )) && max=$count
26194                         echo "$count stripes created on MDT$i"
26195                 done
26196
26197                 min=$($LFS getdirstripe $testdir/* |
26198                         grep -c -P "^\s+$min_index\t")
26199                 (( max - min > num * stripe_count / 10 )) ||
26200                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26201         fi
26202 }
26203
26204 most_full_mdt() {
26205         local ffree
26206         local bavail
26207         local bsize
26208         local min
26209         local min_index
26210         local tmp
26211
26212         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26213         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26214         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26215
26216         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26217         min_index=0
26218         for ((i = 1; i < ${#ffree[@]}; i++)); do
26219                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26220                 (( tmp < min )) && min=$tmp && min_index=$i
26221         done
26222
26223         echo -n $min_index
26224 }
26225
26226 test_413a() {
26227         [ $MDSCOUNT -lt 2 ] &&
26228                 skip "We need at least 2 MDTs for this test"
26229
26230         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26231                 skip "Need server version at least 2.12.52"
26232
26233         local stripe_count
26234
26235         generate_uneven_mdts 100
26236         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26237                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26238                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26239                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26240                         error "mkdir failed"
26241                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26242         done
26243 }
26244 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26245
26246 test_413b() {
26247         [ $MDSCOUNT -lt 2 ] &&
26248                 skip "We need at least 2 MDTs for this test"
26249
26250         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26251                 skip "Need server version at least 2.12.52"
26252
26253         local testdir
26254         local stripe_count
26255
26256         generate_uneven_mdts 100
26257         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26258                 testdir=$DIR/$tdir-s$stripe_count
26259                 mkdir $testdir || error "mkdir $testdir failed"
26260                 mkdir $testdir/rr || error "mkdir rr failed"
26261                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26262                         error "mkdir qos failed"
26263                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26264                         $testdir/rr || error "setdirstripe rr failed"
26265                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26266                         error "setdirstripe failed"
26267                 test_qos_mkdir "mkdir" $stripe_count
26268         done
26269 }
26270 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26271
26272 test_413c() {
26273         (( $MDSCOUNT >= 2 )) ||
26274                 skip "We need at least 2 MDTs for this test"
26275
26276         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26277                 skip "Need server version at least 2.14.51"
26278
26279         local testdir
26280         local inherit
26281         local inherit_rr
26282
26283         testdir=$DIR/${tdir}-s1
26284         mkdir $testdir || error "mkdir $testdir failed"
26285         mkdir $testdir/rr || error "mkdir rr failed"
26286         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26287         # default max_inherit is -1, default max_inherit_rr is 0
26288         $LFS setdirstripe -D -c 1 $testdir/rr ||
26289                 error "setdirstripe rr failed"
26290         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26291                 error "setdirstripe qos failed"
26292         test_qos_mkdir "mkdir" 1
26293
26294         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26295         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26296         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26297         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26298         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26299
26300         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26301         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26302         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26303         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26304         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26305         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26306         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26307                 error "level2 shouldn't have default LMV" || true
26308 }
26309 run_test 413c "mkdir with default LMV max inherit rr"
26310
26311 test_413d() {
26312         (( MDSCOUNT >= 2 )) ||
26313                 skip "We need at least 2 MDTs for this test"
26314
26315         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26316                 skip "Need server version at least 2.14.51"
26317
26318         local lmv_qos_threshold_rr
26319
26320         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26321                 head -n1)
26322         stack_trap "$LCTL set_param \
26323                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26324
26325         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26326         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26327         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26328                 error "$tdir shouldn't have default LMV"
26329         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26330                 error "mkdir sub failed"
26331
26332         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26333
26334         (( count == 100 )) || error "$count subdirs on MDT0"
26335 }
26336 run_test 413d "inherit ROOT default LMV"
26337
26338 test_413e() {
26339         (( MDSCOUNT >= 2 )) ||
26340                 skip "We need at least 2 MDTs for this test"
26341         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26342                 skip "Need server version at least 2.14.55"
26343
26344         local testdir=$DIR/$tdir
26345         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26346         local max_inherit
26347         local sub_max_inherit
26348
26349         mkdir -p $testdir || error "failed to create $testdir"
26350
26351         # set default max-inherit to -1 if stripe count is 0 or 1
26352         $LFS setdirstripe -D -c 1 $testdir ||
26353                 error "failed to set default LMV"
26354         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26355         (( max_inherit == -1 )) ||
26356                 error "wrong max_inherit value $max_inherit"
26357
26358         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26359         $LFS setdirstripe -D -c -1 $testdir ||
26360                 error "failed to set default LMV"
26361         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26362         (( max_inherit > 0 )) ||
26363                 error "wrong max_inherit value $max_inherit"
26364
26365         # and the subdir will decrease the max_inherit by 1
26366         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26367         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26368         (( sub_max_inherit == max_inherit - 1)) ||
26369                 error "wrong max-inherit of subdir $sub_max_inherit"
26370
26371         # check specified --max-inherit and warning message
26372         stack_trap "rm -f $tmpfile"
26373         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26374                 error "failed to set default LMV"
26375         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26376         (( max_inherit == -1 )) ||
26377                 error "wrong max_inherit value $max_inherit"
26378
26379         # check the warning messages
26380         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26381                 error "failed to detect warning string"
26382         fi
26383 }
26384 run_test 413e "check default max-inherit value"
26385
26386 test_fs_dmv_inherit()
26387 {
26388         local testdir=$DIR/$tdir
26389
26390         local count
26391         local inherit
26392         local inherit_rr
26393
26394         for i in 1 2 3; do
26395                 mkdir $testdir || error "mkdir $testdir failed"
26396                 count=$($LFS getdirstripe -D -c $testdir)
26397                 (( count == 1 )) ||
26398                         error "$testdir default LMV count mismatch $count != 1"
26399                 inherit=$($LFS getdirstripe -D -X $testdir)
26400                 (( inherit == 3 - i )) ||
26401                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26402                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26403                 (( inherit_rr == 3 - i )) ||
26404                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26405                 testdir=$testdir/sub
26406         done
26407
26408         mkdir $testdir || error "mkdir $testdir failed"
26409         count=$($LFS getdirstripe -D -c $testdir)
26410         (( count == 0 )) ||
26411                 error "$testdir default LMV count not zero: $count"
26412 }
26413
26414 test_413f() {
26415         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26416
26417         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26418                 skip "Need server version at least 2.14.55"
26419
26420         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26421                 error "dump $DIR default LMV failed"
26422         stack_trap "setfattr --restore=$TMP/dmv.ea"
26423
26424         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26425                 error "set $DIR default LMV failed"
26426
26427         test_fs_dmv_inherit
26428 }
26429 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26430
26431 test_413g() {
26432         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26433
26434         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26435         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26436                 error "dump $DIR default LMV failed"
26437         stack_trap "setfattr --restore=$TMP/dmv.ea"
26438
26439         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26440                 error "set $DIR default LMV failed"
26441
26442         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26443                 error "mount $MOUNT2 failed"
26444         stack_trap "umount_client $MOUNT2"
26445
26446         local saved_DIR=$DIR
26447
26448         export DIR=$MOUNT2
26449
26450         stack_trap "export DIR=$saved_DIR"
26451
26452         # first check filesystem-wide default LMV inheritance
26453         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26454
26455         # then check subdirs are spread to all MDTs
26456         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26457
26458         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26459
26460         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26461 }
26462 run_test 413g "enforce ROOT default LMV on subdir mount"
26463
26464 test_413h() {
26465         (( MDSCOUNT >= 2 )) ||
26466                 skip "We need at least 2 MDTs for this test"
26467
26468         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26469                 skip "Need server version at least 2.15.50.6"
26470
26471         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26472
26473         stack_trap "$LCTL set_param \
26474                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26475         $LCTL set_param lmv.*.qos_maxage=1
26476
26477         local depth=5
26478         local rr_depth=4
26479         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26480         local count=$((MDSCOUNT * 20))
26481
26482         generate_uneven_mdts 50
26483
26484         mkdir -p $dir || error "mkdir $dir failed"
26485         stack_trap "rm -rf $dir"
26486         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26487                 --max-inherit-rr=$rr_depth $dir
26488
26489         for ((d=0; d < depth + 2; d++)); do
26490                 log "dir=$dir:"
26491                 for ((sub=0; sub < count; sub++)); do
26492                         mkdir $dir/d$sub
26493                 done
26494                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26495                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26496                 # subdirs within $rr_depth should be created round-robin
26497                 if (( d < rr_depth )); then
26498                         (( ${num[0]} != count )) ||
26499                                 error "all objects created on MDT ${num[1]}"
26500                 fi
26501
26502                 dir=$dir/d0
26503         done
26504 }
26505 run_test 413h "don't stick to parent for round-robin dirs"
26506
26507 test_413z() {
26508         local pids=""
26509         local subdir
26510         local pid
26511
26512         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26513                 unlinkmany $subdir/f. $TEST413_COUNT &
26514                 pids="$pids $!"
26515         done
26516
26517         for pid in $pids; do
26518                 wait $pid
26519         done
26520 }
26521 run_test 413z "413 test cleanup"
26522
26523 test_414() {
26524 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26525         $LCTL set_param fail_loc=0x80000521
26526         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26527         rm -f $DIR/$tfile
26528 }
26529 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26530
26531 test_415() {
26532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26533         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26534                 skip "Need server version at least 2.11.52"
26535
26536         # LU-11102
26537         local total
26538         local setattr_pid
26539         local start_time
26540         local end_time
26541         local duration
26542
26543         total=500
26544         # this test may be slow on ZFS
26545         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26546
26547         # though this test is designed for striped directory, let's test normal
26548         # directory too since lock is always saved as CoS lock.
26549         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26550         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26551
26552         (
26553                 while true; do
26554                         touch $DIR/$tdir
26555                 done
26556         ) &
26557         setattr_pid=$!
26558
26559         start_time=$(date +%s)
26560         for i in $(seq $total); do
26561                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26562                         > /dev/null
26563         done
26564         end_time=$(date +%s)
26565         duration=$((end_time - start_time))
26566
26567         kill -9 $setattr_pid
26568
26569         echo "rename $total files took $duration sec"
26570         [ $duration -lt 100 ] || error "rename took $duration sec"
26571 }
26572 run_test 415 "lock revoke is not missing"
26573
26574 test_416() {
26575         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26576                 skip "Need server version at least 2.11.55"
26577
26578         # define OBD_FAIL_OSD_TXN_START    0x19a
26579         do_facet mds1 lctl set_param fail_loc=0x19a
26580
26581         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26582
26583         true
26584 }
26585 run_test 416 "transaction start failure won't cause system hung"
26586
26587 cleanup_417() {
26588         trap 0
26589         do_nodes $(comma_list $(mdts_nodes)) \
26590                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26591         do_nodes $(comma_list $(mdts_nodes)) \
26592                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26593         do_nodes $(comma_list $(mdts_nodes)) \
26594                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26595 }
26596
26597 test_417() {
26598         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26599         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26600                 skip "Need MDS version at least 2.11.56"
26601
26602         trap cleanup_417 RETURN EXIT
26603
26604         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26605         do_nodes $(comma_list $(mdts_nodes)) \
26606                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26607         $LFS migrate -m 0 $DIR/$tdir.1 &&
26608                 error "migrate dir $tdir.1 should fail"
26609
26610         do_nodes $(comma_list $(mdts_nodes)) \
26611                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26612         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26613                 error "create remote dir $tdir.2 should fail"
26614
26615         do_nodes $(comma_list $(mdts_nodes)) \
26616                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26617         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26618                 error "create striped dir $tdir.3 should fail"
26619         true
26620 }
26621 run_test 417 "disable remote dir, striped dir and dir migration"
26622
26623 # Checks that the outputs of df [-i] and lfs df [-i] match
26624 #
26625 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26626 check_lfs_df() {
26627         local dir=$2
26628         local inodes
26629         local df_out
26630         local lfs_df_out
26631         local count
26632         local passed=false
26633
26634         # blocks or inodes
26635         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26636
26637         for count in {1..100}; do
26638                 do_nodes "$CLIENTS" \
26639                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26640                 sync; sleep 0.2
26641
26642                 # read the lines of interest
26643                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26644                         error "df $inodes $dir | tail -n +2 failed"
26645                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26646                         error "lfs df $inodes $dir | grep summary: failed"
26647
26648                 # skip first substrings of each output as they are different
26649                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26650                 # compare the two outputs
26651                 passed=true
26652                 #  skip "available" on MDT until LU-13997 is fixed.
26653                 #for i in {1..5}; do
26654                 for i in 1 2 4 5; do
26655                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26656                 done
26657                 $passed && break
26658         done
26659
26660         if ! $passed; then
26661                 df -P $inodes $dir
26662                 echo
26663                 lfs df $inodes $dir
26664                 error "df and lfs df $1 output mismatch: "      \
26665                       "df ${inodes}: ${df_out[*]}, "            \
26666                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26667         fi
26668 }
26669
26670 test_418() {
26671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26672
26673         local dir=$DIR/$tdir
26674         local numfiles=$((RANDOM % 4096 + 2))
26675         local numblocks=$((RANDOM % 256 + 1))
26676
26677         wait_delete_completed
26678         test_mkdir $dir
26679
26680         # check block output
26681         check_lfs_df blocks $dir
26682         # check inode output
26683         check_lfs_df inodes $dir
26684
26685         # create a single file and retest
26686         echo "Creating a single file and testing"
26687         createmany -o $dir/$tfile- 1 &>/dev/null ||
26688                 error "creating 1 file in $dir failed"
26689         check_lfs_df blocks $dir
26690         check_lfs_df inodes $dir
26691
26692         # create a random number of files
26693         echo "Creating $((numfiles - 1)) files and testing"
26694         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26695                 error "creating $((numfiles - 1)) files in $dir failed"
26696
26697         # write a random number of blocks to the first test file
26698         echo "Writing $numblocks 4K blocks and testing"
26699         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26700                 count=$numblocks &>/dev/null ||
26701                 error "dd to $dir/${tfile}-0 failed"
26702
26703         # retest
26704         check_lfs_df blocks $dir
26705         check_lfs_df inodes $dir
26706
26707         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26708                 error "unlinking $numfiles files in $dir failed"
26709 }
26710 run_test 418 "df and lfs df outputs match"
26711
26712 test_419()
26713 {
26714         local dir=$DIR/$tdir
26715
26716         mkdir -p $dir
26717         touch $dir/file
26718
26719         cancel_lru_locks mdc
26720
26721         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26722         $LCTL set_param fail_loc=0x1410
26723         cat $dir/file
26724         $LCTL set_param fail_loc=0
26725         rm -rf $dir
26726 }
26727 run_test 419 "Verify open file by name doesn't crash kernel"
26728
26729 test_420()
26730 {
26731         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26732                 skip "Need MDS version at least 2.12.53"
26733
26734         local SAVE_UMASK=$(umask)
26735         local dir=$DIR/$tdir
26736         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26737
26738         mkdir -p $dir
26739         umask 0000
26740         mkdir -m03777 $dir/testdir
26741         ls -dn $dir/testdir
26742         # Need to remove trailing '.' when SELinux is enabled
26743         local dirperms=$(ls -dn $dir/testdir |
26744                          awk '{ sub(/\.$/, "", $1); print $1}')
26745         [ $dirperms == "drwxrwsrwt" ] ||
26746                 error "incorrect perms on $dir/testdir"
26747
26748         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26749                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26750         ls -n $dir/testdir/testfile
26751         local fileperms=$(ls -n $dir/testdir/testfile |
26752                           awk '{ sub(/\.$/, "", $1); print $1}')
26753         [ $fileperms == "-rwxr-xr-x" ] ||
26754                 error "incorrect perms on $dir/testdir/testfile"
26755
26756         umask $SAVE_UMASK
26757 }
26758 run_test 420 "clear SGID bit on non-directories for non-members"
26759
26760 test_421a() {
26761         local cnt
26762         local fid1
26763         local fid2
26764
26765         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26766                 skip "Need MDS version at least 2.12.54"
26767
26768         test_mkdir $DIR/$tdir
26769         createmany -o $DIR/$tdir/f 3
26770         cnt=$(ls -1 $DIR/$tdir | wc -l)
26771         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26772
26773         fid1=$(lfs path2fid $DIR/$tdir/f1)
26774         fid2=$(lfs path2fid $DIR/$tdir/f2)
26775         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26776
26777         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26778         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26779
26780         cnt=$(ls -1 $DIR/$tdir | wc -l)
26781         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26782
26783         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26784         createmany -o $DIR/$tdir/f 3
26785         cnt=$(ls -1 $DIR/$tdir | wc -l)
26786         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26787
26788         fid1=$(lfs path2fid $DIR/$tdir/f1)
26789         fid2=$(lfs path2fid $DIR/$tdir/f2)
26790         echo "remove using fsname $FSNAME"
26791         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26792
26793         cnt=$(ls -1 $DIR/$tdir | wc -l)
26794         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26795 }
26796 run_test 421a "simple rm by fid"
26797
26798 test_421b() {
26799         local cnt
26800         local FID1
26801         local FID2
26802
26803         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26804                 skip "Need MDS version at least 2.12.54"
26805
26806         test_mkdir $DIR/$tdir
26807         createmany -o $DIR/$tdir/f 3
26808         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26809         MULTIPID=$!
26810
26811         FID1=$(lfs path2fid $DIR/$tdir/f1)
26812         FID2=$(lfs path2fid $DIR/$tdir/f2)
26813         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26814
26815         kill -USR1 $MULTIPID
26816         wait
26817
26818         cnt=$(ls $DIR/$tdir | wc -l)
26819         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26820 }
26821 run_test 421b "rm by fid on open file"
26822
26823 test_421c() {
26824         local cnt
26825         local FIDS
26826
26827         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26828                 skip "Need MDS version at least 2.12.54"
26829
26830         test_mkdir $DIR/$tdir
26831         createmany -o $DIR/$tdir/f 3
26832         touch $DIR/$tdir/$tfile
26833         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26834         cnt=$(ls -1 $DIR/$tdir | wc -l)
26835         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26836
26837         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26838         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26839
26840         cnt=$(ls $DIR/$tdir | wc -l)
26841         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26842 }
26843 run_test 421c "rm by fid against hardlinked files"
26844
26845 test_421d() {
26846         local cnt
26847         local FIDS
26848
26849         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26850                 skip "Need MDS version at least 2.12.54"
26851
26852         test_mkdir $DIR/$tdir
26853         createmany -o $DIR/$tdir/f 4097
26854         cnt=$(ls -1 $DIR/$tdir | wc -l)
26855         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26856
26857         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26858         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26859
26860         cnt=$(ls $DIR/$tdir | wc -l)
26861         rm -rf $DIR/$tdir
26862         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26863 }
26864 run_test 421d "rmfid en masse"
26865
26866 test_421e() {
26867         local cnt
26868         local FID
26869
26870         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26871         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26872                 skip "Need MDS version at least 2.12.54"
26873
26874         mkdir -p $DIR/$tdir
26875         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26876         createmany -o $DIR/$tdir/striped_dir/f 512
26877         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26878         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26879
26880         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26881                 sed "s/[/][^:]*://g")
26882         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26883
26884         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26885         rm -rf $DIR/$tdir
26886         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26887 }
26888 run_test 421e "rmfid in DNE"
26889
26890 test_421f() {
26891         local cnt
26892         local FID
26893
26894         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26895                 skip "Need MDS version at least 2.12.54"
26896
26897         test_mkdir $DIR/$tdir
26898         touch $DIR/$tdir/f
26899         cnt=$(ls -1 $DIR/$tdir | wc -l)
26900         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26901
26902         FID=$(lfs path2fid $DIR/$tdir/f)
26903         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26904         # rmfid should fail
26905         cnt=$(ls -1 $DIR/$tdir | wc -l)
26906         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26907
26908         chmod a+rw $DIR/$tdir
26909         ls -la $DIR/$tdir
26910         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26911         # rmfid should fail
26912         cnt=$(ls -1 $DIR/$tdir | wc -l)
26913         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26914
26915         rm -f $DIR/$tdir/f
26916         $RUNAS touch $DIR/$tdir/f
26917         FID=$(lfs path2fid $DIR/$tdir/f)
26918         echo "rmfid as root"
26919         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26920         cnt=$(ls -1 $DIR/$tdir | wc -l)
26921         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26922
26923         rm -f $DIR/$tdir/f
26924         $RUNAS touch $DIR/$tdir/f
26925         cnt=$(ls -1 $DIR/$tdir | wc -l)
26926         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26927         FID=$(lfs path2fid $DIR/$tdir/f)
26928         # rmfid w/o user_fid2path mount option should fail
26929         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26930         cnt=$(ls -1 $DIR/$tdir | wc -l)
26931         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26932
26933         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26934         stack_trap "rmdir $tmpdir"
26935         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26936                 error "failed to mount client'"
26937         stack_trap "umount_client $tmpdir"
26938
26939         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26940         # rmfid should succeed
26941         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26942         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26943
26944         # rmfid shouldn't allow to remove files due to dir's permission
26945         chmod a+rwx $tmpdir/$tdir
26946         touch $tmpdir/$tdir/f
26947         ls -la $tmpdir/$tdir
26948         FID=$(lfs path2fid $tmpdir/$tdir/f)
26949         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26950         return 0
26951 }
26952 run_test 421f "rmfid checks permissions"
26953
26954 test_421g() {
26955         local cnt
26956         local FIDS
26957
26958         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26959         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26960                 skip "Need MDS version at least 2.12.54"
26961
26962         mkdir -p $DIR/$tdir
26963         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26964         createmany -o $DIR/$tdir/striped_dir/f 512
26965         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26966         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26967
26968         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26969                 sed "s/[/][^:]*://g")
26970
26971         rm -f $DIR/$tdir/striped_dir/f1*
26972         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26973         removed=$((512 - cnt))
26974
26975         # few files have been just removed, so we expect
26976         # rmfid to fail on their fids
26977         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26978         [ $removed != $errors ] && error "$errors != $removed"
26979
26980         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26981         rm -rf $DIR/$tdir
26982         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26983 }
26984 run_test 421g "rmfid to return errors properly"
26985
26986 test_422() {
26987         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26988         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26989         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26990         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26991         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26992
26993         local amc=$(at_max_get client)
26994         local amo=$(at_max_get mds1)
26995         local timeout=`lctl get_param -n timeout`
26996
26997         at_max_set 0 client
26998         at_max_set 0 mds1
26999
27000 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27001         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27002                         fail_val=$(((2*timeout + 10)*1000))
27003         touch $DIR/$tdir/d3/file &
27004         sleep 2
27005 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27006         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27007                         fail_val=$((2*timeout + 5))
27008         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27009         local pid=$!
27010         sleep 1
27011         kill -9 $pid
27012         sleep $((2 * timeout))
27013         echo kill $pid
27014         kill -9 $pid
27015         lctl mark touch
27016         touch $DIR/$tdir/d2/file3
27017         touch $DIR/$tdir/d2/file4
27018         touch $DIR/$tdir/d2/file5
27019
27020         wait
27021         at_max_set $amc client
27022         at_max_set $amo mds1
27023
27024         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27025         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27026                 error "Watchdog is always throttled"
27027 }
27028 run_test 422 "kill a process with RPC in progress"
27029
27030 stat_test() {
27031     df -h $MOUNT &
27032     df -h $MOUNT &
27033     df -h $MOUNT &
27034     df -h $MOUNT &
27035     df -h $MOUNT &
27036     df -h $MOUNT &
27037 }
27038
27039 test_423() {
27040     local _stats
27041     # ensure statfs cache is expired
27042     sleep 2;
27043
27044     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27045     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27046
27047     return 0
27048 }
27049 run_test 423 "statfs should return a right data"
27050
27051 test_424() {
27052 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27053         $LCTL set_param fail_loc=0x80000522
27054         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27055         rm -f $DIR/$tfile
27056 }
27057 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27058
27059 test_425() {
27060         test_mkdir -c -1 $DIR/$tdir
27061         $LFS setstripe -c -1 $DIR/$tdir
27062
27063         lru_resize_disable "" 100
27064         stack_trap "lru_resize_enable" EXIT
27065
27066         sleep 5
27067
27068         for i in $(seq $((MDSCOUNT * 125))); do
27069                 local t=$DIR/$tdir/$tfile_$i
27070
27071                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27072                         error_noexit "Create file $t"
27073         done
27074         stack_trap "rm -rf $DIR/$tdir" EXIT
27075
27076         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27077                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27078                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27079
27080                 [ $lock_count -le $lru_size ] ||
27081                         error "osc lock count $lock_count > lru size $lru_size"
27082         done
27083
27084         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27085                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27086                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27087
27088                 [ $lock_count -le $lru_size ] ||
27089                         error "mdc lock count $lock_count > lru size $lru_size"
27090         done
27091 }
27092 run_test 425 "lock count should not exceed lru size"
27093
27094 test_426() {
27095         splice-test -r $DIR/$tfile
27096         splice-test -rd $DIR/$tfile
27097         splice-test $DIR/$tfile
27098         splice-test -d $DIR/$tfile
27099 }
27100 run_test 426 "splice test on Lustre"
27101
27102 test_427() {
27103         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27104         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27105                 skip "Need MDS version at least 2.12.4"
27106         local log
27107
27108         mkdir $DIR/$tdir
27109         mkdir $DIR/$tdir/1
27110         mkdir $DIR/$tdir/2
27111         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27112         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27113
27114         $LFS getdirstripe $DIR/$tdir/1/dir
27115
27116         #first setfattr for creating updatelog
27117         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27118
27119 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27120         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27121         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27122         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27123
27124         sleep 2
27125         fail mds2
27126         wait_recovery_complete mds2 $((2*TIMEOUT))
27127
27128         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27129         echo $log | grep "get update log failed" &&
27130                 error "update log corruption is detected" || true
27131 }
27132 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27133
27134 test_428() {
27135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27136         local cache_limit=$CACHE_MAX
27137
27138         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27139         $LCTL set_param -n llite.*.max_cached_mb=64
27140
27141         mkdir $DIR/$tdir
27142         $LFS setstripe -c 1 $DIR/$tdir
27143         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27144         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27145         #test write
27146         for f in $(seq 4); do
27147                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27148         done
27149         wait
27150
27151         cancel_lru_locks osc
27152         # Test read
27153         for f in $(seq 4); do
27154                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27155         done
27156         wait
27157 }
27158 run_test 428 "large block size IO should not hang"
27159
27160 test_429() { # LU-7915 / LU-10948
27161         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27162         local testfile=$DIR/$tfile
27163         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27164         local new_flag=1
27165         local first_rpc
27166         local second_rpc
27167         local third_rpc
27168
27169         $LCTL get_param $ll_opencache_threshold_count ||
27170                 skip "client does not have opencache parameter"
27171
27172         set_opencache $new_flag
27173         stack_trap "restore_opencache"
27174         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27175                 error "enable opencache failed"
27176         touch $testfile
27177         # drop MDC DLM locks
27178         cancel_lru_locks mdc
27179         # clear MDC RPC stats counters
27180         $LCTL set_param $mdc_rpcstats=clear
27181
27182         # According to the current implementation, we need to run 3 times
27183         # open & close file to verify if opencache is enabled correctly.
27184         # 1st, RPCs are sent for lookup/open and open handle is released on
27185         #      close finally.
27186         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27187         #      so open handle won't be released thereafter.
27188         # 3rd, No RPC is sent out.
27189         $MULTIOP $testfile oc || error "multiop failed"
27190         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27191         echo "1st: $first_rpc RPCs in flight"
27192
27193         $MULTIOP $testfile oc || error "multiop failed"
27194         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27195         echo "2nd: $second_rpc RPCs in flight"
27196
27197         $MULTIOP $testfile oc || error "multiop failed"
27198         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27199         echo "3rd: $third_rpc RPCs in flight"
27200
27201         #verify no MDC RPC is sent
27202         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27203 }
27204 run_test 429 "verify if opencache flag on client side does work"
27205
27206 lseek_test_430() {
27207         local offset
27208         local file=$1
27209
27210         # data at [200K, 400K)
27211         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27212                 error "256K->512K dd fails"
27213         # data at [2M, 3M)
27214         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27215                 error "2M->3M dd fails"
27216         # data at [4M, 5M)
27217         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27218                 error "4M->5M dd fails"
27219         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27220         # start at first component hole #1
27221         printf "Seeking hole from 1000 ... "
27222         offset=$(lseek_test -l 1000 $file)
27223         echo $offset
27224         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27225         printf "Seeking data from 1000 ... "
27226         offset=$(lseek_test -d 1000 $file)
27227         echo $offset
27228         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27229
27230         # start at first component data block
27231         printf "Seeking hole from 300000 ... "
27232         offset=$(lseek_test -l 300000 $file)
27233         echo $offset
27234         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27235         printf "Seeking data from 300000 ... "
27236         offset=$(lseek_test -d 300000 $file)
27237         echo $offset
27238         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27239
27240         # start at the first component but beyond end of object size
27241         printf "Seeking hole from 1000000 ... "
27242         offset=$(lseek_test -l 1000000 $file)
27243         echo $offset
27244         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27245         printf "Seeking data from 1000000 ... "
27246         offset=$(lseek_test -d 1000000 $file)
27247         echo $offset
27248         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27249
27250         # start at second component stripe 2 (empty file)
27251         printf "Seeking hole from 1500000 ... "
27252         offset=$(lseek_test -l 1500000 $file)
27253         echo $offset
27254         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27255         printf "Seeking data from 1500000 ... "
27256         offset=$(lseek_test -d 1500000 $file)
27257         echo $offset
27258         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27259
27260         # start at second component stripe 1 (all data)
27261         printf "Seeking hole from 3000000 ... "
27262         offset=$(lseek_test -l 3000000 $file)
27263         echo $offset
27264         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27265         printf "Seeking data from 3000000 ... "
27266         offset=$(lseek_test -d 3000000 $file)
27267         echo $offset
27268         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27269
27270         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27271                 error "2nd dd fails"
27272         echo "Add data block at 640K...1280K"
27273
27274         # start at before new data block, in hole
27275         printf "Seeking hole from 600000 ... "
27276         offset=$(lseek_test -l 600000 $file)
27277         echo $offset
27278         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27279         printf "Seeking data from 600000 ... "
27280         offset=$(lseek_test -d 600000 $file)
27281         echo $offset
27282         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27283
27284         # start at the first component new data block
27285         printf "Seeking hole from 1000000 ... "
27286         offset=$(lseek_test -l 1000000 $file)
27287         echo $offset
27288         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27289         printf "Seeking data from 1000000 ... "
27290         offset=$(lseek_test -d 1000000 $file)
27291         echo $offset
27292         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27293
27294         # start at second component stripe 2, new data
27295         printf "Seeking hole from 1200000 ... "
27296         offset=$(lseek_test -l 1200000 $file)
27297         echo $offset
27298         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27299         printf "Seeking data from 1200000 ... "
27300         offset=$(lseek_test -d 1200000 $file)
27301         echo $offset
27302         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27303
27304         # start beyond file end
27305         printf "Using offset > filesize ... "
27306         lseek_test -l 4000000 $file && error "lseek should fail"
27307         printf "Using offset > filesize ... "
27308         lseek_test -d 4000000 $file && error "lseek should fail"
27309
27310         printf "Done\n\n"
27311 }
27312
27313 test_430a() {
27314         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27315                 skip "MDT does not support SEEK_HOLE"
27316
27317         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27318                 skip "OST does not support SEEK_HOLE"
27319
27320         local file=$DIR/$tdir/$tfile
27321
27322         mkdir -p $DIR/$tdir
27323
27324         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27325         # OST stripe #1 will have continuous data at [1M, 3M)
27326         # OST stripe #2 is empty
27327         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27328         lseek_test_430 $file
27329         rm $file
27330         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27331         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27332         lseek_test_430 $file
27333         rm $file
27334         $LFS setstripe -c2 -S 512K $file
27335         echo "Two stripes, stripe size 512K"
27336         lseek_test_430 $file
27337         rm $file
27338         # FLR with stale mirror
27339         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27340                        -N -c2 -S 1M $file
27341         echo "Mirrored file:"
27342         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27343         echo "Plain 2 stripes 1M"
27344         lseek_test_430 $file
27345         rm $file
27346 }
27347 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27348
27349 test_430b() {
27350         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27351                 skip "OST does not support SEEK_HOLE"
27352
27353         local offset
27354         local file=$DIR/$tdir/$tfile
27355
27356         mkdir -p $DIR/$tdir
27357         # Empty layout lseek should fail
27358         $MCREATE $file
27359         # seek from 0
27360         printf "Seeking hole from 0 ... "
27361         lseek_test -l 0 $file && error "lseek should fail"
27362         printf "Seeking data from 0 ... "
27363         lseek_test -d 0 $file && error "lseek should fail"
27364         rm $file
27365
27366         # 1M-hole file
27367         $LFS setstripe -E 1M -c2 -E eof $file
27368         $TRUNCATE $file 1048576
27369         printf "Seeking hole from 1000000 ... "
27370         offset=$(lseek_test -l 1000000 $file)
27371         echo $offset
27372         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27373         printf "Seeking data from 1000000 ... "
27374         lseek_test -d 1000000 $file && error "lseek should fail"
27375         rm $file
27376
27377         # full component followed by non-inited one
27378         $LFS setstripe -E 1M -c2 -E eof $file
27379         dd if=/dev/urandom of=$file bs=1M count=1
27380         printf "Seeking hole from 1000000 ... "
27381         offset=$(lseek_test -l 1000000 $file)
27382         echo $offset
27383         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27384         printf "Seeking hole from 1048576 ... "
27385         lseek_test -l 1048576 $file && error "lseek should fail"
27386         # init second component and truncate back
27387         echo "123" >> $file
27388         $TRUNCATE $file 1048576
27389         printf "Seeking hole from 1000000 ... "
27390         offset=$(lseek_test -l 1000000 $file)
27391         echo $offset
27392         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27393         printf "Seeking hole from 1048576 ... "
27394         lseek_test -l 1048576 $file && error "lseek should fail"
27395         # boundary checks for big values
27396         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27397         offset=$(lseek_test -d 0 $file.10g)
27398         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27399         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27400         offset=$(lseek_test -d 0 $file.100g)
27401         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27402         return 0
27403 }
27404 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27405
27406 test_430c() {
27407         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27408                 skip "OST does not support SEEK_HOLE"
27409
27410         local file=$DIR/$tdir/$tfile
27411         local start
27412
27413         mkdir -p $DIR/$tdir
27414         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27415
27416         # cp version 8.33+ prefers lseek over fiemap
27417         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27418                 start=$SECONDS
27419                 time cp $file /dev/null
27420                 (( SECONDS - start < 5 )) ||
27421                         error "cp: too long runtime $((SECONDS - start))"
27422
27423         fi
27424         # tar version 1.29+ supports SEEK_HOLE/DATA
27425         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27426                 start=$SECONDS
27427                 time tar cS $file - | cat > /dev/null
27428                 (( SECONDS - start < 5 )) ||
27429                         error "tar: too long runtime $((SECONDS - start))"
27430         fi
27431 }
27432 run_test 430c "lseek: external tools check"
27433
27434 test_431() { # LU-14187
27435         local file=$DIR/$tdir/$tfile
27436
27437         mkdir -p $DIR/$tdir
27438         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27439         dd if=/dev/urandom of=$file bs=4k count=1
27440         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27441         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27442         #define OBD_FAIL_OST_RESTART_IO 0x251
27443         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27444         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27445         cp $file $file.0
27446         cancel_lru_locks
27447         sync_all_data
27448         echo 3 > /proc/sys/vm/drop_caches
27449         diff  $file $file.0 || error "data diff"
27450 }
27451 run_test 431 "Restart transaction for IO"
27452
27453 cleanup_test_432() {
27454         do_facet mgs $LCTL nodemap_activate 0
27455         wait_nm_sync active
27456 }
27457
27458 test_432() {
27459         local tmpdir=$TMP/dir432
27460
27461         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27462                 skip "Need MDS version at least 2.14.52"
27463
27464         stack_trap cleanup_test_432 EXIT
27465         mkdir $DIR/$tdir
27466         mkdir $tmpdir
27467
27468         do_facet mgs $LCTL nodemap_activate 1
27469         wait_nm_sync active
27470         do_facet mgs $LCTL nodemap_modify --name default \
27471                 --property admin --value 1
27472         do_facet mgs $LCTL nodemap_modify --name default \
27473                 --property trusted --value 1
27474         cancel_lru_locks mdc
27475         wait_nm_sync default admin_nodemap
27476         wait_nm_sync default trusted_nodemap
27477
27478         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27479                grep -ci "Operation not permitted") -ne 0 ]; then
27480                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27481         fi
27482 }
27483 run_test 432 "mv dir from outside Lustre"
27484
27485 test_433() {
27486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27487
27488         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27489                 skip "inode cache not supported"
27490
27491         $LCTL set_param llite.*.inode_cache=0
27492         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27493
27494         local count=256
27495         local before
27496         local after
27497
27498         cancel_lru_locks mdc
27499         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27500         createmany -m $DIR/$tdir/f $count
27501         createmany -d $DIR/$tdir/d $count
27502         ls -l $DIR/$tdir > /dev/null
27503         stack_trap "rm -rf $DIR/$tdir"
27504
27505         before=$(num_objects)
27506         cancel_lru_locks mdc
27507         after=$(num_objects)
27508
27509         # sometimes even @before is less than 2 * count
27510         while (( before - after < count )); do
27511                 sleep 1
27512                 after=$(num_objects)
27513                 wait=$((wait + 1))
27514                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27515                 if (( wait > 60 )); then
27516                         error "inode slab grew from $before to $after"
27517                 fi
27518         done
27519
27520         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27521 }
27522 run_test 433 "ldlm lock cancel releases dentries and inodes"
27523
27524 prep_801() {
27525         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27526         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27527                 skip "Need server version at least 2.9.55"
27528
27529         start_full_debug_logging
27530 }
27531
27532 post_801() {
27533         stop_full_debug_logging
27534 }
27535
27536 barrier_stat() {
27537         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27538                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27539                            awk '/The barrier for/ { print $7 }')
27540                 echo $st
27541         else
27542                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27543                 echo \'$st\'
27544         fi
27545 }
27546
27547 barrier_expired() {
27548         local expired
27549
27550         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27551                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27552                           awk '/will be expired/ { print $7 }')
27553         else
27554                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27555         fi
27556
27557         echo $expired
27558 }
27559
27560 test_801a() {
27561         prep_801
27562
27563         echo "Start barrier_freeze at: $(date)"
27564         #define OBD_FAIL_BARRIER_DELAY          0x2202
27565         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27566         # Do not reduce barrier time - See LU-11873
27567         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27568
27569         sleep 2
27570         local b_status=$(barrier_stat)
27571         echo "Got barrier status at: $(date)"
27572         [ "$b_status" = "'freezing_p1'" ] ||
27573                 error "(1) unexpected barrier status $b_status"
27574
27575         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27576         wait
27577         b_status=$(barrier_stat)
27578         [ "$b_status" = "'frozen'" ] ||
27579                 error "(2) unexpected barrier status $b_status"
27580
27581         local expired=$(barrier_expired)
27582         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27583         sleep $((expired + 3))
27584
27585         b_status=$(barrier_stat)
27586         [ "$b_status" = "'expired'" ] ||
27587                 error "(3) unexpected barrier status $b_status"
27588
27589         # Do not reduce barrier time - See LU-11873
27590         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27591                 error "(4) fail to freeze barrier"
27592
27593         b_status=$(barrier_stat)
27594         [ "$b_status" = "'frozen'" ] ||
27595                 error "(5) unexpected barrier status $b_status"
27596
27597         echo "Start barrier_thaw at: $(date)"
27598         #define OBD_FAIL_BARRIER_DELAY          0x2202
27599         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27600         do_facet mgs $LCTL barrier_thaw $FSNAME &
27601
27602         sleep 2
27603         b_status=$(barrier_stat)
27604         echo "Got barrier status at: $(date)"
27605         [ "$b_status" = "'thawing'" ] ||
27606                 error "(6) unexpected barrier status $b_status"
27607
27608         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27609         wait
27610         b_status=$(barrier_stat)
27611         [ "$b_status" = "'thawed'" ] ||
27612                 error "(7) unexpected barrier status $b_status"
27613
27614         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27615         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27616         do_facet mgs $LCTL barrier_freeze $FSNAME
27617
27618         b_status=$(barrier_stat)
27619         [ "$b_status" = "'failed'" ] ||
27620                 error "(8) unexpected barrier status $b_status"
27621
27622         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27623         do_facet mgs $LCTL barrier_thaw $FSNAME
27624
27625         post_801
27626 }
27627 run_test 801a "write barrier user interfaces and stat machine"
27628
27629 test_801b() {
27630         prep_801
27631
27632         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27633         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27634         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27635         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27636         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27637
27638         cancel_lru_locks mdc
27639
27640         # 180 seconds should be long enough
27641         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27642
27643         local b_status=$(barrier_stat)
27644         [ "$b_status" = "'frozen'" ] ||
27645                 error "(6) unexpected barrier status $b_status"
27646
27647         mkdir $DIR/$tdir/d0/d10 &
27648         mkdir_pid=$!
27649
27650         touch $DIR/$tdir/d1/f13 &
27651         touch_pid=$!
27652
27653         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27654         ln_pid=$!
27655
27656         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27657         mv_pid=$!
27658
27659         rm -f $DIR/$tdir/d4/f12 &
27660         rm_pid=$!
27661
27662         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27663
27664         # To guarantee taht the 'stat' is not blocked
27665         b_status=$(barrier_stat)
27666         [ "$b_status" = "'frozen'" ] ||
27667                 error "(8) unexpected barrier status $b_status"
27668
27669         # let above commands to run at background
27670         sleep 5
27671
27672         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27673         ps -p $touch_pid || error "(10) touch should be blocked"
27674         ps -p $ln_pid || error "(11) link should be blocked"
27675         ps -p $mv_pid || error "(12) rename should be blocked"
27676         ps -p $rm_pid || error "(13) unlink should be blocked"
27677
27678         b_status=$(barrier_stat)
27679         [ "$b_status" = "'frozen'" ] ||
27680                 error "(14) unexpected barrier status $b_status"
27681
27682         do_facet mgs $LCTL barrier_thaw $FSNAME
27683         b_status=$(barrier_stat)
27684         [ "$b_status" = "'thawed'" ] ||
27685                 error "(15) unexpected barrier status $b_status"
27686
27687         wait $mkdir_pid || error "(16) mkdir should succeed"
27688         wait $touch_pid || error "(17) touch should succeed"
27689         wait $ln_pid || error "(18) link should succeed"
27690         wait $mv_pid || error "(19) rename should succeed"
27691         wait $rm_pid || error "(20) unlink should succeed"
27692
27693         post_801
27694 }
27695 run_test 801b "modification will be blocked by write barrier"
27696
27697 test_801c() {
27698         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27699
27700         prep_801
27701
27702         stop mds2 || error "(1) Fail to stop mds2"
27703
27704         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27705
27706         local b_status=$(barrier_stat)
27707         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27708                 do_facet mgs $LCTL barrier_thaw $FSNAME
27709                 error "(2) unexpected barrier status $b_status"
27710         }
27711
27712         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27713                 error "(3) Fail to rescan barrier bitmap"
27714
27715         # Do not reduce barrier time - See LU-11873
27716         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27717
27718         b_status=$(barrier_stat)
27719         [ "$b_status" = "'frozen'" ] ||
27720                 error "(4) unexpected barrier status $b_status"
27721
27722         do_facet mgs $LCTL barrier_thaw $FSNAME
27723         b_status=$(barrier_stat)
27724         [ "$b_status" = "'thawed'" ] ||
27725                 error "(5) unexpected barrier status $b_status"
27726
27727         local devname=$(mdsdevname 2)
27728
27729         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27730
27731         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27732                 error "(7) Fail to rescan barrier bitmap"
27733
27734         post_801
27735 }
27736 run_test 801c "rescan barrier bitmap"
27737
27738 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27739 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27740 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27741 saved_MOUNT_OPTS=$MOUNT_OPTS
27742
27743 cleanup_802a() {
27744         trap 0
27745
27746         stopall
27747         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27748         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27749         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27750         MOUNT_OPTS=$saved_MOUNT_OPTS
27751         setupall
27752 }
27753
27754 test_802a() {
27755         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27756         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27757         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27758                 skip "Need server version at least 2.9.55"
27759
27760         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27761
27762         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27763
27764         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27765                 error "(2) Fail to copy"
27766
27767         trap cleanup_802a EXIT
27768
27769         # sync by force before remount as readonly
27770         sync; sync_all_data; sleep 3; sync_all_data
27771
27772         stopall
27773
27774         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27775         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27776         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27777
27778         echo "Mount the server as read only"
27779         setupall server_only || error "(3) Fail to start servers"
27780
27781         echo "Mount client without ro should fail"
27782         mount_client $MOUNT &&
27783                 error "(4) Mount client without 'ro' should fail"
27784
27785         echo "Mount client with ro should succeed"
27786         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27787         mount_client $MOUNT ||
27788                 error "(5) Mount client with 'ro' should succeed"
27789
27790         echo "Modify should be refused"
27791         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27792
27793         echo "Read should be allowed"
27794         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27795                 error "(7) Read should succeed under ro mode"
27796
27797         cleanup_802a
27798 }
27799 run_test 802a "simulate readonly device"
27800
27801 test_802b() {
27802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27803         remote_mds_nodsh && skip "remote MDS with nodsh"
27804
27805         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27806                 skip "readonly option not available"
27807
27808         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27809
27810         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27811                 error "(2) Fail to copy"
27812
27813         # write back all cached data before setting MDT to readonly
27814         cancel_lru_locks
27815         sync_all_data
27816
27817         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27818         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27819
27820         echo "Modify should be refused"
27821         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27822
27823         echo "Read should be allowed"
27824         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27825                 error "(7) Read should succeed under ro mode"
27826
27827         # disable readonly
27828         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27829 }
27830 run_test 802b "be able to set MDTs to readonly"
27831
27832 test_803a() {
27833         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27834         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27835                 skip "MDS needs to be newer than 2.10.54"
27836
27837         mkdir_on_mdt0 $DIR/$tdir
27838         # Create some objects on all MDTs to trigger related logs objects
27839         for idx in $(seq $MDSCOUNT); do
27840                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27841                         $DIR/$tdir/dir${idx} ||
27842                         error "Fail to create $DIR/$tdir/dir${idx}"
27843         done
27844
27845         wait_delete_completed # ensure old test cleanups are finished
27846         sleep 3
27847         echo "before create:"
27848         $LFS df -i $MOUNT
27849         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27850
27851         for i in {1..10}; do
27852                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27853                         error "Fail to create $DIR/$tdir/foo$i"
27854         done
27855
27856         # sync ZFS-on-MDS to refresh statfs data
27857         wait_zfs_commit mds1
27858         sleep 3
27859         echo "after create:"
27860         $LFS df -i $MOUNT
27861         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27862
27863         # allow for an llog to be cleaned up during the test
27864         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27865                 error "before ($before_used) + 10 > after ($after_used)"
27866
27867         for i in {1..10}; do
27868                 rm -rf $DIR/$tdir/foo$i ||
27869                         error "Fail to remove $DIR/$tdir/foo$i"
27870         done
27871
27872         # sync ZFS-on-MDS to refresh statfs data
27873         wait_zfs_commit mds1
27874         wait_delete_completed
27875         sleep 3 # avoid MDT return cached statfs
27876         echo "after unlink:"
27877         $LFS df -i $MOUNT
27878         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27879
27880         # allow for an llog to be created during the test
27881         [ $after_used -le $((before_used + 1)) ] ||
27882                 error "after ($after_used) > before ($before_used) + 1"
27883 }
27884 run_test 803a "verify agent object for remote object"
27885
27886 test_803b() {
27887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27888         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27889                 skip "MDS needs to be newer than 2.13.56"
27890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27891
27892         for i in $(seq 0 $((MDSCOUNT - 1))); do
27893                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27894         done
27895
27896         local before=0
27897         local after=0
27898
27899         local tmp
27900
27901         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27902         for i in $(seq 0 $((MDSCOUNT - 1))); do
27903                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27904                         awk '/getattr/ { print $2 }')
27905                 before=$((before + tmp))
27906         done
27907         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27908         for i in $(seq 0 $((MDSCOUNT - 1))); do
27909                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27910                         awk '/getattr/ { print $2 }')
27911                 after=$((after + tmp))
27912         done
27913
27914         [ $before -eq $after ] || error "getattr count $before != $after"
27915 }
27916 run_test 803b "remote object can getattr from cache"
27917
27918 test_804() {
27919         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27920         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27921                 skip "MDS needs to be newer than 2.10.54"
27922         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27923
27924         mkdir -p $DIR/$tdir
27925         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27926                 error "Fail to create $DIR/$tdir/dir0"
27927
27928         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27929         local dev=$(mdsdevname 2)
27930
27931         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27932                 grep ${fid} || error "NOT found agent entry for dir0"
27933
27934         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27935                 error "Fail to create $DIR/$tdir/dir1"
27936
27937         touch $DIR/$tdir/dir1/foo0 ||
27938                 error "Fail to create $DIR/$tdir/dir1/foo0"
27939         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27940         local rc=0
27941
27942         for idx in $(seq $MDSCOUNT); do
27943                 dev=$(mdsdevname $idx)
27944                 do_facet mds${idx} \
27945                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27946                         grep ${fid} && rc=$idx
27947         done
27948
27949         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27950                 error "Fail to rename foo0 to foo1"
27951         if [ $rc -eq 0 ]; then
27952                 for idx in $(seq $MDSCOUNT); do
27953                         dev=$(mdsdevname $idx)
27954                         do_facet mds${idx} \
27955                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27956                         grep ${fid} && rc=$idx
27957                 done
27958         fi
27959
27960         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27961                 error "Fail to rename foo1 to foo2"
27962         if [ $rc -eq 0 ]; then
27963                 for idx in $(seq $MDSCOUNT); do
27964                         dev=$(mdsdevname $idx)
27965                         do_facet mds${idx} \
27966                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27967                         grep ${fid} && rc=$idx
27968                 done
27969         fi
27970
27971         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27972
27973         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27974                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27975         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27976                 error "Fail to rename foo2 to foo0"
27977         unlink $DIR/$tdir/dir1/foo0 ||
27978                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27979         rm -rf $DIR/$tdir/dir0 ||
27980                 error "Fail to rm $DIR/$tdir/dir0"
27981
27982         for idx in $(seq $MDSCOUNT); do
27983                 rc=0
27984
27985                 stop mds${idx}
27986                 dev=$(mdsdevname $idx)
27987                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27988                         rc=$?
27989                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27990                         error "mount mds$idx failed"
27991                 df $MOUNT > /dev/null 2>&1
27992
27993                 # e2fsck should not return error
27994                 [ $rc -eq 0 ] ||
27995                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27996         done
27997 }
27998 run_test 804 "verify agent entry for remote entry"
27999
28000 cleanup_805() {
28001         do_facet $SINGLEMDS zfs set quota=$old $fsset
28002         unlinkmany $DIR/$tdir/f- 1000000
28003         trap 0
28004 }
28005
28006 test_805() {
28007         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28008         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28009         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28010                 skip "netfree not implemented before 0.7"
28011         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28012                 skip "Need MDS version at least 2.10.57"
28013
28014         local fsset
28015         local freekb
28016         local usedkb
28017         local old
28018         local quota
28019         local pref="osd-zfs.$FSNAME-MDT0000."
28020
28021         # limit available space on MDS dataset to meet nospace issue
28022         # quickly. then ZFS 0.7.2 can use reserved space if asked
28023         # properly (using netfree flag in osd_declare_destroy()
28024         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28025         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28026                 gawk '{print $3}')
28027         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28028         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28029         let "usedkb=usedkb-freekb"
28030         let "freekb=freekb/2"
28031         if let "freekb > 5000"; then
28032                 let "freekb=5000"
28033         fi
28034         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28035         trap cleanup_805 EXIT
28036         mkdir_on_mdt0 $DIR/$tdir
28037         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28038                 error "Can't set PFL layout"
28039         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28040         rm -rf $DIR/$tdir || error "not able to remove"
28041         do_facet $SINGLEMDS zfs set quota=$old $fsset
28042         trap 0
28043 }
28044 run_test 805 "ZFS can remove from full fs"
28045
28046 # Size-on-MDS test
28047 check_lsom_data()
28048 {
28049         local file=$1
28050         local expect=$(stat -c %s $file)
28051
28052         check_lsom_size $1 $expect
28053
28054         local blocks=$($LFS getsom -b $file)
28055         expect=$(stat -c %b $file)
28056         [[ $blocks == $expect ]] ||
28057                 error "$file expected blocks: $expect, got: $blocks"
28058 }
28059
28060 check_lsom_size()
28061 {
28062         local size
28063         local expect=$2
28064
28065         cancel_lru_locks mdc
28066
28067         size=$($LFS getsom -s $1)
28068         [[ $size == $expect ]] ||
28069                 error "$file expected size: $expect, got: $size"
28070 }
28071
28072 test_806() {
28073         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28074                 skip "Need MDS version at least 2.11.52"
28075
28076         local bs=1048576
28077
28078         touch $DIR/$tfile || error "touch $tfile failed"
28079
28080         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28081         save_lustre_params client "llite.*.xattr_cache" > $save
28082         lctl set_param llite.*.xattr_cache=0
28083         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28084
28085         # single-threaded write
28086         echo "Test SOM for single-threaded write"
28087         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28088                 error "write $tfile failed"
28089         check_lsom_size $DIR/$tfile $bs
28090
28091         local num=32
28092         local size=$(($num * $bs))
28093         local offset=0
28094         local i
28095
28096         echo "Test SOM for single client multi-threaded($num) write"
28097         $TRUNCATE $DIR/$tfile 0
28098         for ((i = 0; i < $num; i++)); do
28099                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28100                 local pids[$i]=$!
28101                 offset=$((offset + $bs))
28102         done
28103         for (( i=0; i < $num; i++ )); do
28104                 wait ${pids[$i]}
28105         done
28106         check_lsom_size $DIR/$tfile $size
28107
28108         $TRUNCATE $DIR/$tfile 0
28109         for ((i = 0; i < $num; i++)); do
28110                 offset=$((offset - $bs))
28111                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28112                 local pids[$i]=$!
28113         done
28114         for (( i=0; i < $num; i++ )); do
28115                 wait ${pids[$i]}
28116         done
28117         check_lsom_size $DIR/$tfile $size
28118
28119         # multi-client writes
28120         num=$(get_node_count ${CLIENTS//,/ })
28121         size=$(($num * $bs))
28122         offset=0
28123         i=0
28124
28125         echo "Test SOM for multi-client ($num) writes"
28126         $TRUNCATE $DIR/$tfile 0
28127         for client in ${CLIENTS//,/ }; do
28128                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28129                 local pids[$i]=$!
28130                 i=$((i + 1))
28131                 offset=$((offset + $bs))
28132         done
28133         for (( i=0; i < $num; i++ )); do
28134                 wait ${pids[$i]}
28135         done
28136         check_lsom_size $DIR/$tfile $offset
28137
28138         i=0
28139         $TRUNCATE $DIR/$tfile 0
28140         for client in ${CLIENTS//,/ }; do
28141                 offset=$((offset - $bs))
28142                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28143                 local pids[$i]=$!
28144                 i=$((i + 1))
28145         done
28146         for (( i=0; i < $num; i++ )); do
28147                 wait ${pids[$i]}
28148         done
28149         check_lsom_size $DIR/$tfile $size
28150
28151         # verify truncate
28152         echo "Test SOM for truncate"
28153         $TRUNCATE $DIR/$tfile 1048576
28154         check_lsom_size $DIR/$tfile 1048576
28155         $TRUNCATE $DIR/$tfile 1234
28156         check_lsom_size $DIR/$tfile 1234
28157
28158         # verify SOM blocks count
28159         echo "Verify SOM block count"
28160         $TRUNCATE $DIR/$tfile 0
28161         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28162                 error "failed to write file $tfile"
28163         check_lsom_data $DIR/$tfile
28164 }
28165 run_test 806 "Verify Lazy Size on MDS"
28166
28167 test_807() {
28168         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28169         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28170                 skip "Need MDS version at least 2.11.52"
28171
28172         # Registration step
28173         changelog_register || error "changelog_register failed"
28174         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28175         changelog_users $SINGLEMDS | grep -q $cl_user ||
28176                 error "User $cl_user not found in changelog_users"
28177
28178         rm -rf $DIR/$tdir || error "rm $tdir failed"
28179         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28180         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28181         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28182         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28183                 error "truncate $tdir/trunc failed"
28184
28185         local bs=1048576
28186         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28187                 error "write $tfile failed"
28188
28189         # multi-client wirtes
28190         local num=$(get_node_count ${CLIENTS//,/ })
28191         local offset=0
28192         local i=0
28193
28194         echo "Test SOM for multi-client ($num) writes"
28195         touch $DIR/$tfile || error "touch $tfile failed"
28196         $TRUNCATE $DIR/$tfile 0
28197         for client in ${CLIENTS//,/ }; do
28198                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28199                 local pids[$i]=$!
28200                 i=$((i + 1))
28201                 offset=$((offset + $bs))
28202         done
28203         for (( i=0; i < $num; i++ )); do
28204                 wait ${pids[$i]}
28205         done
28206
28207         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28208         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28209         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28210         check_lsom_data $DIR/$tdir/trunc
28211         check_lsom_data $DIR/$tdir/single_dd
28212         check_lsom_data $DIR/$tfile
28213
28214         rm -rf $DIR/$tdir
28215         # Deregistration step
28216         changelog_deregister || error "changelog_deregister failed"
28217 }
28218 run_test 807 "verify LSOM syncing tool"
28219
28220 check_som_nologged()
28221 {
28222         local lines=$($LFS changelog $FSNAME-MDT0000 |
28223                 grep 'x=trusted.som' | wc -l)
28224         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28225 }
28226
28227 test_808() {
28228         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28229                 skip "Need MDS version at least 2.11.55"
28230
28231         # Registration step
28232         changelog_register || error "changelog_register failed"
28233
28234         touch $DIR/$tfile || error "touch $tfile failed"
28235         check_som_nologged
28236
28237         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28238                 error "write $tfile failed"
28239         check_som_nologged
28240
28241         $TRUNCATE $DIR/$tfile 1234
28242         check_som_nologged
28243
28244         $TRUNCATE $DIR/$tfile 1048576
28245         check_som_nologged
28246
28247         # Deregistration step
28248         changelog_deregister || error "changelog_deregister failed"
28249 }
28250 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28251
28252 check_som_nodata()
28253 {
28254         $LFS getsom $1
28255         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28256 }
28257
28258 test_809() {
28259         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28260                 skip "Need MDS version at least 2.11.56"
28261
28262         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28263                 error "failed to create DoM-only file $DIR/$tfile"
28264         touch $DIR/$tfile || error "touch $tfile failed"
28265         check_som_nodata $DIR/$tfile
28266
28267         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28268                 error "write $tfile failed"
28269         check_som_nodata $DIR/$tfile
28270
28271         $TRUNCATE $DIR/$tfile 1234
28272         check_som_nodata $DIR/$tfile
28273
28274         $TRUNCATE $DIR/$tfile 4097
28275         check_som_nodata $DIR/$file
28276 }
28277 run_test 809 "Verify no SOM xattr store for DoM-only files"
28278
28279 test_810() {
28280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28281         $GSS && skip_env "could not run with gss"
28282         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28283                 skip "OST < 2.12.58 doesn't align checksum"
28284
28285         set_checksums 1
28286         stack_trap "set_checksums $ORIG_CSUM" EXIT
28287         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28288
28289         local csum
28290         local before
28291         local after
28292         for csum in $CKSUM_TYPES; do
28293                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28294                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28295                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28296                         eval set -- $i
28297                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28298                         before=$(md5sum $DIR/$tfile)
28299                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28300                         after=$(md5sum $DIR/$tfile)
28301                         [ "$before" == "$after" ] ||
28302                                 error "$csum: $before != $after bs=$1 seek=$2"
28303                 done
28304         done
28305 }
28306 run_test 810 "partial page writes on ZFS (LU-11663)"
28307
28308 test_812a() {
28309         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28310                 skip "OST < 2.12.51 doesn't support this fail_loc"
28311
28312         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28313         # ensure ost1 is connected
28314         stat $DIR/$tfile >/dev/null || error "can't stat"
28315         wait_osc_import_state client ost1 FULL
28316         # no locks, no reqs to let the connection idle
28317         cancel_lru_locks osc
28318
28319         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28320 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28321         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28322         wait_osc_import_state client ost1 CONNECTING
28323         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28324
28325         stat $DIR/$tfile >/dev/null || error "can't stat file"
28326 }
28327 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28328
28329 test_812b() { # LU-12378
28330         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28331                 skip "OST < 2.12.51 doesn't support this fail_loc"
28332
28333         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28334         # ensure ost1 is connected
28335         stat $DIR/$tfile >/dev/null || error "can't stat"
28336         wait_osc_import_state client ost1 FULL
28337         # no locks, no reqs to let the connection idle
28338         cancel_lru_locks osc
28339
28340         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28341 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28342         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28343         wait_osc_import_state client ost1 CONNECTING
28344         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28345
28346         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28347         wait_osc_import_state client ost1 IDLE
28348 }
28349 run_test 812b "do not drop no resend request for idle connect"
28350
28351 test_812c() {
28352         local old
28353
28354         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28355
28356         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28357         $LFS getstripe $DIR/$tfile
28358         $LCTL set_param osc.*.idle_timeout=10
28359         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28360         # ensure ost1 is connected
28361         stat $DIR/$tfile >/dev/null || error "can't stat"
28362         wait_osc_import_state client ost1 FULL
28363         # no locks, no reqs to let the connection idle
28364         cancel_lru_locks osc
28365
28366 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28367         $LCTL set_param fail_loc=0x80000533
28368         sleep 15
28369         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28370 }
28371 run_test 812c "idle import vs lock enqueue race"
28372
28373 test_813() {
28374         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28375         [ -z "$file_heat_sav" ] && skip "no file heat support"
28376
28377         local readsample
28378         local writesample
28379         local readbyte
28380         local writebyte
28381         local readsample1
28382         local writesample1
28383         local readbyte1
28384         local writebyte1
28385
28386         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28387         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28388
28389         $LCTL set_param -n llite.*.file_heat=1
28390         echo "Turn on file heat"
28391         echo "Period second: $period_second, Decay percentage: $decay_pct"
28392
28393         echo "QQQQ" > $DIR/$tfile
28394         echo "QQQQ" > $DIR/$tfile
28395         echo "QQQQ" > $DIR/$tfile
28396         cat $DIR/$tfile > /dev/null
28397         cat $DIR/$tfile > /dev/null
28398         cat $DIR/$tfile > /dev/null
28399         cat $DIR/$tfile > /dev/null
28400
28401         local out=$($LFS heat_get $DIR/$tfile)
28402
28403         $LFS heat_get $DIR/$tfile
28404         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28405         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28406         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28407         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28408
28409         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28410         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28411         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28412         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28413
28414         sleep $((period_second + 3))
28415         echo "Sleep $((period_second + 3)) seconds..."
28416         # The recursion formula to calculate the heat of the file f is as
28417         # follow:
28418         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28419         # Where Hi is the heat value in the period between time points i*I and
28420         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28421         # to the weight of Ci.
28422         out=$($LFS heat_get $DIR/$tfile)
28423         $LFS heat_get $DIR/$tfile
28424         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28425         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28426         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28427         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28428
28429         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28430                 error "read sample ($readsample) is wrong"
28431         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28432                 error "write sample ($writesample) is wrong"
28433         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28434                 error "read bytes ($readbyte) is wrong"
28435         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28436                 error "write bytes ($writebyte) is wrong"
28437
28438         echo "QQQQ" > $DIR/$tfile
28439         echo "QQQQ" > $DIR/$tfile
28440         echo "QQQQ" > $DIR/$tfile
28441         cat $DIR/$tfile > /dev/null
28442         cat $DIR/$tfile > /dev/null
28443         cat $DIR/$tfile > /dev/null
28444         cat $DIR/$tfile > /dev/null
28445
28446         sleep $((period_second + 3))
28447         echo "Sleep $((period_second + 3)) seconds..."
28448
28449         out=$($LFS heat_get $DIR/$tfile)
28450         $LFS heat_get $DIR/$tfile
28451         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28452         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28453         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28454         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28455
28456         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28457                 4 * $decay_pct) / 100") -eq 1 ] ||
28458                 error "read sample ($readsample1) is wrong"
28459         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28460                 3 * $decay_pct) / 100") -eq 1 ] ||
28461                 error "write sample ($writesample1) is wrong"
28462         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28463                 20 * $decay_pct) / 100") -eq 1 ] ||
28464                 error "read bytes ($readbyte1) is wrong"
28465         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28466                 15 * $decay_pct) / 100") -eq 1 ] ||
28467                 error "write bytes ($writebyte1) is wrong"
28468
28469         echo "Turn off file heat for the file $DIR/$tfile"
28470         $LFS heat_set -o $DIR/$tfile
28471
28472         echo "QQQQ" > $DIR/$tfile
28473         echo "QQQQ" > $DIR/$tfile
28474         echo "QQQQ" > $DIR/$tfile
28475         cat $DIR/$tfile > /dev/null
28476         cat $DIR/$tfile > /dev/null
28477         cat $DIR/$tfile > /dev/null
28478         cat $DIR/$tfile > /dev/null
28479
28480         out=$($LFS heat_get $DIR/$tfile)
28481         $LFS heat_get $DIR/$tfile
28482         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28483         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28484         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28485         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28486
28487         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28488         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28489         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28490         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28491
28492         echo "Trun on file heat for the file $DIR/$tfile"
28493         $LFS heat_set -O $DIR/$tfile
28494
28495         echo "QQQQ" > $DIR/$tfile
28496         echo "QQQQ" > $DIR/$tfile
28497         echo "QQQQ" > $DIR/$tfile
28498         cat $DIR/$tfile > /dev/null
28499         cat $DIR/$tfile > /dev/null
28500         cat $DIR/$tfile > /dev/null
28501         cat $DIR/$tfile > /dev/null
28502
28503         out=$($LFS heat_get $DIR/$tfile)
28504         $LFS heat_get $DIR/$tfile
28505         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28506         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28507         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28508         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28509
28510         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28511         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28512         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28513         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28514
28515         $LFS heat_set -c $DIR/$tfile
28516         $LCTL set_param -n llite.*.file_heat=0
28517         echo "Turn off file heat support for the Lustre filesystem"
28518
28519         echo "QQQQ" > $DIR/$tfile
28520         echo "QQQQ" > $DIR/$tfile
28521         echo "QQQQ" > $DIR/$tfile
28522         cat $DIR/$tfile > /dev/null
28523         cat $DIR/$tfile > /dev/null
28524         cat $DIR/$tfile > /dev/null
28525         cat $DIR/$tfile > /dev/null
28526
28527         out=$($LFS heat_get $DIR/$tfile)
28528         $LFS heat_get $DIR/$tfile
28529         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28530         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28531         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28532         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28533
28534         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28535         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28536         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28537         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28538
28539         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28540         rm -f $DIR/$tfile
28541 }
28542 run_test 813 "File heat verfication"
28543
28544 test_814()
28545 {
28546         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28547         echo -n y >> $DIR/$tfile
28548         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28549         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28550 }
28551 run_test 814 "sparse cp works as expected (LU-12361)"
28552
28553 test_815()
28554 {
28555         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28556         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28557 }
28558 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28559
28560 test_816() {
28561         local ost1_imp=$(get_osc_import_name client ost1)
28562         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28563                          cut -d'.' -f2)
28564
28565         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28566         # ensure ost1 is connected
28567
28568         stat $DIR/$tfile >/dev/null || error "can't stat"
28569         wait_osc_import_state client ost1 FULL
28570         # no locks, no reqs to let the connection idle
28571         cancel_lru_locks osc
28572         lru_resize_disable osc
28573         local before
28574         local now
28575         before=$($LCTL get_param -n \
28576                  ldlm.namespaces.$imp_name.lru_size)
28577
28578         wait_osc_import_state client ost1 IDLE
28579         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28580         now=$($LCTL get_param -n \
28581               ldlm.namespaces.$imp_name.lru_size)
28582         [ $before == $now ] || error "lru_size changed $before != $now"
28583 }
28584 run_test 816 "do not reset lru_resize on idle reconnect"
28585
28586 cleanup_817() {
28587         umount $tmpdir
28588         exportfs -u localhost:$DIR/nfsexp
28589         rm -rf $DIR/nfsexp
28590 }
28591
28592 test_817() {
28593         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28594
28595         mkdir -p $DIR/nfsexp
28596         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28597                 error "failed to export nfs"
28598
28599         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28600         stack_trap cleanup_817 EXIT
28601
28602         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28603                 error "failed to mount nfs to $tmpdir"
28604
28605         cp /bin/true $tmpdir
28606         $DIR/nfsexp/true || error "failed to execute 'true' command"
28607 }
28608 run_test 817 "nfsd won't cache write lock for exec file"
28609
28610 test_818() {
28611         test_mkdir -i0 -c1 $DIR/$tdir
28612         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28613         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28614         stop $SINGLEMDS
28615
28616         # restore osp-syn threads
28617         stack_trap "fail $SINGLEMDS"
28618
28619         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28620         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28621         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28622                 error "start $SINGLEMDS failed"
28623         rm -rf $DIR/$tdir
28624
28625         local testid=$(echo $TESTNAME | tr '_' ' ')
28626
28627         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28628                 grep "run LFSCK" || error "run LFSCK is not suggested"
28629 }
28630 run_test 818 "unlink with failed llog"
28631
28632 test_819a() {
28633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28634         cancel_lru_locks osc
28635         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28636         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28637         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28638         rm -f $TDIR/$tfile
28639 }
28640 run_test 819a "too big niobuf in read"
28641
28642 test_819b() {
28643         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28644         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28645         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28646         cancel_lru_locks osc
28647         sleep 1
28648         rm -f $TDIR/$tfile
28649 }
28650 run_test 819b "too big niobuf in write"
28651
28652
28653 function test_820_start_ost() {
28654         sleep 5
28655
28656         for num in $(seq $OSTCOUNT); do
28657                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28658         done
28659 }
28660
28661 test_820() {
28662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28663
28664         mkdir $DIR/$tdir
28665         umount_client $MOUNT || error "umount failed"
28666         for num in $(seq $OSTCOUNT); do
28667                 stop ost$num
28668         done
28669
28670         # mount client with no active OSTs
28671         # so that the client can't initialize max LOV EA size
28672         # from OSC notifications
28673         mount_client $MOUNT || error "mount failed"
28674         # delay OST starting to keep this 0 max EA size for a while
28675         test_820_start_ost &
28676
28677         # create a directory on MDS2
28678         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28679                 error "Failed to create directory"
28680         # open intent should update default EA size
28681         # see mdc_update_max_ea_from_body()
28682         # notice this is the very first RPC to MDS2
28683         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28684         ret=$?
28685         echo $out
28686         # With SSK, this situation can lead to -EPERM being returned.
28687         # In that case, simply retry.
28688         if [ $ret -ne 0 ] && $SHARED_KEY; then
28689                 if echo "$out" | grep -q "not permitted"; then
28690                         cp /etc/services $DIR/$tdir/mds2
28691                         ret=$?
28692                 fi
28693         fi
28694         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28695 }
28696 run_test 820 "update max EA from open intent"
28697
28698 test_823() {
28699         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28700         local OST_MAX_PRECREATE=20000
28701
28702         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28703                 skip "Need MDS version at least 2.14.56"
28704
28705         save_lustre_params mds1 \
28706                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28707         do_facet $SINGLEMDS "$LCTL set_param -n \
28708                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28709         do_facet $SINGLEMDS "$LCTL set_param -n \
28710                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28711
28712         stack_trap "restore_lustre_params < $p; rm $p"
28713
28714         do_facet $SINGLEMDS "$LCTL set_param -n \
28715                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28716
28717         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28718                       osp.$FSNAME-OST0000*MDT0000.create_count")
28719         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28720                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28721         local expect_count=$(((($max/2)/256) * 256))
28722
28723         log "setting create_count to 100200:"
28724         log " -result- count: $count with max: $max, expecting: $expect_count"
28725
28726         [[ $count -eq expect_count ]] ||
28727                 error "Create count not set to max precreate."
28728 }
28729 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28730
28731 test_831() {
28732         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28733                 skip "Need MDS version 2.14.56"
28734
28735         local sync_changes=$(do_facet $SINGLEMDS \
28736                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28737
28738         [ "$sync_changes" -gt 100 ] &&
28739                 skip "Sync changes $sync_changes > 100 already"
28740
28741         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28742
28743         $LFS mkdir -i 0 $DIR/$tdir
28744         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28745
28746         save_lustre_params mds1 \
28747                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28748         save_lustre_params mds1 \
28749                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28750
28751         do_facet mds1 "$LCTL set_param -n \
28752                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28753                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28754         stack_trap "restore_lustre_params < $p" EXIT
28755
28756         createmany -o $DIR/$tdir/f- 1000
28757         unlinkmany $DIR/$tdir/f- 1000 &
28758         local UNLINK_PID=$!
28759
28760         while sleep 1; do
28761                 sync_changes=$(do_facet mds1 \
28762                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28763                 # the check in the code is racy, fail the test
28764                 # if the value above the limit by 10.
28765                 [ $sync_changes -gt 110 ] && {
28766                         kill -2 $UNLINK_PID
28767                         wait
28768                         error "osp changes throttling failed, $sync_changes>110"
28769                 }
28770                 kill -0 $UNLINK_PID 2> /dev/null || break
28771         done
28772         wait
28773 }
28774 run_test 831 "throttling unlink/setattr queuing on OSP"
28775
28776 #
28777 # tests that do cleanup/setup should be run at the end
28778 #
28779
28780 test_900() {
28781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28782         local ls
28783
28784         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28785         $LCTL set_param fail_loc=0x903
28786
28787         cancel_lru_locks MGC
28788
28789         FAIL_ON_ERROR=true cleanup
28790         FAIL_ON_ERROR=true setup
28791 }
28792 run_test 900 "umount should not race with any mgc requeue thread"
28793
28794 # LUS-6253/LU-11185
28795 test_901() {
28796         local old
28797         local count
28798         local oldc
28799         local newc
28800         local olds
28801         local news
28802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28803
28804         # some get_param have a bug to handle dot in param name
28805         cancel_lru_locks MGC
28806         old=$(mount -t lustre | wc -l)
28807         # 1 config+sptlrpc
28808         # 2 params
28809         # 3 nodemap
28810         # 4 IR
28811         old=$((old * 4))
28812         oldc=0
28813         count=0
28814         while [ $old -ne $oldc ]; do
28815                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28816                 sleep 1
28817                 ((count++))
28818                 if [ $count -ge $TIMEOUT ]; then
28819                         error "too large timeout"
28820                 fi
28821         done
28822         umount_client $MOUNT || error "umount failed"
28823         mount_client $MOUNT || error "mount failed"
28824         cancel_lru_locks MGC
28825         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28826
28827         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28828
28829         return 0
28830 }
28831 run_test 901 "don't leak a mgc lock on client umount"
28832
28833 # LU-13377
28834 test_902() {
28835         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28836                 skip "client does not have LU-13377 fix"
28837         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28838         $LCTL set_param fail_loc=0x1415
28839         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28840         cancel_lru_locks osc
28841         rm -f $DIR/$tfile
28842 }
28843 run_test 902 "test short write doesn't hang lustre"
28844
28845 # LU-14711
28846 test_903() {
28847         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28848         echo "blah" > $DIR/${tfile}-2
28849         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28850         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28851         $LCTL set_param fail_loc=0x417 fail_val=20
28852
28853         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28854         sleep 1 # To start the destroy
28855         wait_destroy_complete 150 || error "Destroy taking too long"
28856         cat $DIR/$tfile > /dev/null || error "Evicted"
28857 }
28858 run_test 903 "Test long page discard does not cause evictions"
28859
28860 test_904() {
28861         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28862         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28863                 grep -q project || skip "skip project quota not supported"
28864
28865         local testfile="$DIR/$tdir/$tfile"
28866         local xattr="trusted.projid"
28867         local projid
28868         local mdts=$(comma_list $(mdts_nodes))
28869         local saved=$(do_facet mds1 $LCTL get_param -n \
28870                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28871
28872         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28873         stack_trap "do_nodes $mdts $LCTL set_param \
28874                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28875
28876         mkdir -p $DIR/$tdir
28877         touch $testfile
28878         #hide projid xattr on server
28879         $LFS project -p 1 $testfile ||
28880                 error "set $testfile project id failed"
28881         getfattr -m - $testfile | grep $xattr &&
28882                 error "do not show trusted.projid when disabled on server"
28883         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28884         #should be hidden when projid is 0
28885         $LFS project -p 0 $testfile ||
28886                 error "set $testfile project id failed"
28887         getfattr -m - $testfile | grep $xattr &&
28888                 error "do not show trusted.projid with project ID 0"
28889
28890         #still can getxattr explicitly
28891         projid=$(getfattr -n $xattr $testfile |
28892                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28893         [ $projid == "0" ] ||
28894                 error "projid expected 0 not $projid"
28895
28896         #set the projid via setxattr
28897         setfattr -n $xattr -v "1000" $testfile ||
28898                 error "setattr failed with $?"
28899         projid=($($LFS project $testfile))
28900         [ ${projid[0]} == "1000" ] ||
28901                 error "projid expected 1000 not $projid"
28902
28903         #check the new projid via getxattr
28904         $LFS project -p 1001 $testfile ||
28905                 error "set $testfile project id failed"
28906         getfattr -m - $testfile | grep $xattr ||
28907                 error "should show trusted.projid when project ID != 0"
28908         projid=$(getfattr -n $xattr $testfile |
28909                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28910         [ $projid == "1001" ] ||
28911                 error "projid expected 1001 not $projid"
28912
28913         #try to set invalid projid
28914         setfattr -n $xattr -v "4294967295" $testfile &&
28915                 error "set invalid projid should fail"
28916
28917         #remove the xattr means setting projid to 0
28918         setfattr -x $xattr $testfile ||
28919                 error "setfattr failed with $?"
28920         projid=($($LFS project $testfile))
28921         [ ${projid[0]} == "0" ] ||
28922                 error "projid expected 0 not $projid"
28923
28924         #should be hidden when parent has inherit flag and same projid
28925         $LFS project -srp 1002 $DIR/$tdir ||
28926                 error "set $tdir project id failed"
28927         getfattr -m - $testfile | grep $xattr &&
28928                 error "do not show trusted.projid with inherit flag"
28929
28930         #still can getxattr explicitly
28931         projid=$(getfattr -n $xattr $testfile |
28932                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28933         [ $projid == "1002" ] ||
28934                 error "projid expected 1002 not $projid"
28935 }
28936 run_test 904 "virtual project ID xattr"
28937
28938 # LU-8582
28939 test_905() {
28940         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28941                 skip "lustre < 2.8.54 does not support ladvise"
28942
28943         remote_ost_nodsh && skip "remote OST with nodsh"
28944         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28945
28946         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28947
28948         #define OBD_FAIL_OST_OPCODE 0x253
28949         # OST_LADVISE = 21
28950         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28951         $LFS ladvise -a willread $DIR/$tfile &&
28952                 error "unexpected success of ladvise with fault injection"
28953         $LFS ladvise -a willread $DIR/$tfile |&
28954                 grep -q "Operation not supported"
28955         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28956 }
28957 run_test 905 "bad or new opcode should not stuck client"
28958
28959 test_906() {
28960         grep -q io_uring_setup /proc/kallsyms ||
28961                 skip "Client OS does not support io_uring I/O engine"
28962         io_uring_probe || skip "kernel does not support io_uring fully"
28963         which fio || skip_env "no fio installed"
28964         fio --enghelp | grep -q io_uring ||
28965                 skip_env "fio does not support io_uring I/O engine"
28966
28967         local file=$DIR/$tfile
28968         local ioengine="io_uring"
28969         local numjobs=2
28970         local size=50M
28971
28972         fio --name=seqwrite --ioengine=$ioengine        \
28973                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28974                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28975                 error "fio seqwrite $file failed"
28976
28977         fio --name=seqread --ioengine=$ioengine \
28978                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28979                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28980                 error "fio seqread $file failed"
28981
28982         rm -f $file || error "rm -f $file failed"
28983 }
28984 run_test 906 "Simple test for io_uring I/O engine via fio"
28985
28986 complete $SECONDS
28987 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28988 check_and_cleanup_lustre
28989 if [ "$I_MOUNTED" != "yes" ]; then
28990         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28991 fi
28992 exit_status