Whamcloud - gitweb
LU-16046 revert: "LU-9964 llite: prevent mulitple group locks"
[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 # bug 2543 - update blocks count on client
9629 test_66() {
9630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9631
9632         local COUNT=${COUNT:-8}
9633         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9634         sync; sync_all_data; sync; sync_all_data
9635         cancel_lru_locks osc
9636         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9637         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9638 }
9639 run_test 66 "update inode blocks count on client ==============="
9640
9641 meminfo() {
9642         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9643 }
9644
9645 swap_used() {
9646         swapon -s | awk '($1 == "'$1'") { print $4 }'
9647 }
9648
9649 # bug5265, obdfilter oa2dentry return -ENOENT
9650 # #define OBD_FAIL_SRV_ENOENT 0x217
9651 test_69() {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653         remote_ost_nodsh && skip "remote OST with nodsh"
9654
9655         f="$DIR/$tfile"
9656         $LFS setstripe -c 1 -i 0 $f
9657
9658         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9659
9660         do_facet ost1 lctl set_param fail_loc=0x217
9661         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9662         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9663
9664         do_facet ost1 lctl set_param fail_loc=0
9665         $DIRECTIO write $f 0 2 || error "write error"
9666
9667         cancel_lru_locks osc
9668         $DIRECTIO read $f 0 1 || error "read error"
9669
9670         do_facet ost1 lctl set_param fail_loc=0x217
9671         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9672
9673         do_facet ost1 lctl set_param fail_loc=0
9674         rm -f $f
9675 }
9676 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9677
9678 test_71() {
9679         test_mkdir $DIR/$tdir
9680         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9681         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9682 }
9683 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9684
9685 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9687         [ "$RUNAS_ID" = "$UID" ] &&
9688                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9689         # Check that testing environment is properly set up. Skip if not
9690         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9691                 skip_env "User $RUNAS_ID does not exist - skipping"
9692
9693         touch $DIR/$tfile
9694         chmod 777 $DIR/$tfile
9695         chmod ug+s $DIR/$tfile
9696         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9697                 error "$RUNAS dd $DIR/$tfile failed"
9698         # See if we are still setuid/sgid
9699         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9700                 error "S/gid is not dropped on write"
9701         # Now test that MDS is updated too
9702         cancel_lru_locks mdc
9703         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9704                 error "S/gid is not dropped on MDS"
9705         rm -f $DIR/$tfile
9706 }
9707 run_test 72a "Test that remove suid works properly (bug5695) ===="
9708
9709 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9710         local perm
9711
9712         [ "$RUNAS_ID" = "$UID" ] &&
9713                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9714         [ "$RUNAS_ID" -eq 0 ] &&
9715                 skip_env "RUNAS_ID = 0 -- skipping"
9716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9717         # Check that testing environment is properly set up. Skip if not
9718         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9719                 skip_env "User $RUNAS_ID does not exist - skipping"
9720
9721         touch $DIR/${tfile}-f{g,u}
9722         test_mkdir $DIR/${tfile}-dg
9723         test_mkdir $DIR/${tfile}-du
9724         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9725         chmod g+s $DIR/${tfile}-{f,d}g
9726         chmod u+s $DIR/${tfile}-{f,d}u
9727         for perm in 777 2777 4777; do
9728                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9729                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9730                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9731                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9732         done
9733         true
9734 }
9735 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9736
9737 # bug 3462 - multiple simultaneous MDC requests
9738 test_73() {
9739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9740
9741         test_mkdir $DIR/d73-1
9742         test_mkdir $DIR/d73-2
9743         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9744         pid1=$!
9745
9746         lctl set_param fail_loc=0x80000129
9747         $MULTIOP $DIR/d73-1/f73-2 Oc &
9748         sleep 1
9749         lctl set_param fail_loc=0
9750
9751         $MULTIOP $DIR/d73-2/f73-3 Oc &
9752         pid3=$!
9753
9754         kill -USR1 $pid1
9755         wait $pid1 || return 1
9756
9757         sleep 25
9758
9759         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9760         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9761         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9762
9763         rm -rf $DIR/d73-*
9764 }
9765 run_test 73 "multiple MDC requests (should not deadlock)"
9766
9767 test_74a() { # bug 6149, 6184
9768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9769
9770         touch $DIR/f74a
9771         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9772         #
9773         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9774         # will spin in a tight reconnection loop
9775         $LCTL set_param fail_loc=0x8000030e
9776         # get any lock that won't be difficult - lookup works.
9777         ls $DIR/f74a
9778         $LCTL set_param fail_loc=0
9779         rm -f $DIR/f74a
9780         true
9781 }
9782 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9783
9784 test_74b() { # bug 13310
9785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9786
9787         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9788         #
9789         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9790         # will spin in a tight reconnection loop
9791         $LCTL set_param fail_loc=0x8000030e
9792         # get a "difficult" lock
9793         touch $DIR/f74b
9794         $LCTL set_param fail_loc=0
9795         rm -f $DIR/f74b
9796         true
9797 }
9798 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9799
9800 test_74c() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802
9803         #define OBD_FAIL_LDLM_NEW_LOCK
9804         $LCTL set_param fail_loc=0x319
9805         touch $DIR/$tfile && error "touch successful"
9806         $LCTL set_param fail_loc=0
9807         true
9808 }
9809 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9810
9811 slab_lic=/sys/kernel/slab/lustre_inode_cache
9812 num_objects() {
9813         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9814         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9815                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9816 }
9817
9818 test_76a() { # Now for b=20433, added originally in b=1443
9819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9820
9821         cancel_lru_locks osc
9822         # there may be some slab objects cached per core
9823         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9824         local before=$(num_objects)
9825         local count=$((512 * cpus))
9826         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9827         local margin=$((count / 10))
9828         if [[ -f $slab_lic/aliases ]]; then
9829                 local aliases=$(cat $slab_lic/aliases)
9830                 (( aliases > 0 )) && margin=$((margin * aliases))
9831         fi
9832
9833         echo "before slab objects: $before"
9834         for i in $(seq $count); do
9835                 touch $DIR/$tfile
9836                 rm -f $DIR/$tfile
9837         done
9838         cancel_lru_locks osc
9839         local after=$(num_objects)
9840         echo "created: $count, after slab objects: $after"
9841         # shared slab counts are not very accurate, allow significant margin
9842         # the main goal is that the cache growth is not permanently > $count
9843         while (( after > before + margin )); do
9844                 sleep 1
9845                 after=$(num_objects)
9846                 wait=$((wait + 1))
9847                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9848                 if (( wait > 60 )); then
9849                         error "inode slab grew from $before+$margin to $after"
9850                 fi
9851         done
9852 }
9853 run_test 76a "confirm clients recycle inodes properly ===="
9854
9855 test_76b() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9858
9859         local count=512
9860         local before=$(num_objects)
9861
9862         for i in $(seq $count); do
9863                 mkdir $DIR/$tdir
9864                 rmdir $DIR/$tdir
9865         done
9866
9867         local after=$(num_objects)
9868         local wait=0
9869
9870         while (( after > before )); do
9871                 sleep 1
9872                 after=$(num_objects)
9873                 wait=$((wait + 1))
9874                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9875                 if (( wait > 60 )); then
9876                         error "inode slab grew from $before to $after"
9877                 fi
9878         done
9879
9880         echo "slab objects before: $before, after: $after"
9881 }
9882 run_test 76b "confirm clients recycle directory inodes properly ===="
9883
9884 export ORIG_CSUM=""
9885 set_checksums()
9886 {
9887         # Note: in sptlrpc modes which enable its own bulk checksum, the
9888         # original crc32_le bulk checksum will be automatically disabled,
9889         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9890         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9891         # In this case set_checksums() will not be no-op, because sptlrpc
9892         # bulk checksum will be enabled all through the test.
9893
9894         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9895         lctl set_param -n osc.*.checksums $1
9896         return 0
9897 }
9898
9899 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9900                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9901 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9902                              tr -d [] | head -n1)}
9903 set_checksum_type()
9904 {
9905         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9906         rc=$?
9907         log "set checksum type to $1, rc = $rc"
9908         return $rc
9909 }
9910
9911 get_osc_checksum_type()
9912 {
9913         # arugment 1: OST name, like OST0000
9914         ost=$1
9915         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9916                         sed 's/.*\[\(.*\)\].*/\1/g')
9917         rc=$?
9918         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9919         echo $checksum_type
9920 }
9921
9922 F77_TMP=$TMP/f77-temp
9923 F77SZ=8
9924 setup_f77() {
9925         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9926                 error "error writing to $F77_TMP"
9927 }
9928
9929 test_77a() { # bug 10889
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931         $GSS && skip_env "could not run with gss"
9932
9933         [ ! -f $F77_TMP ] && setup_f77
9934         set_checksums 1
9935         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9936         set_checksums 0
9937         rm -f $DIR/$tfile
9938 }
9939 run_test 77a "normal checksum read/write operation"
9940
9941 test_77b() { # bug 10889
9942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9943         $GSS && skip_env "could not run with gss"
9944
9945         [ ! -f $F77_TMP ] && setup_f77
9946         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9947         $LCTL set_param fail_loc=0x80000409
9948         set_checksums 1
9949
9950         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9951                 error "dd error: $?"
9952         $LCTL set_param fail_loc=0
9953
9954         for algo in $CKSUM_TYPES; do
9955                 cancel_lru_locks osc
9956                 set_checksum_type $algo
9957                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9958                 $LCTL set_param fail_loc=0x80000408
9959                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9960                 $LCTL set_param fail_loc=0
9961         done
9962         set_checksums 0
9963         set_checksum_type $ORIG_CSUM_TYPE
9964         rm -f $DIR/$tfile
9965 }
9966 run_test 77b "checksum error on client write, read"
9967
9968 cleanup_77c() {
9969         trap 0
9970         set_checksums 0
9971         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9972         $check_ost &&
9973                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9974         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9975         $check_ost && [ -n "$ost_file_prefix" ] &&
9976                 do_facet ost1 rm -f ${ost_file_prefix}\*
9977 }
9978
9979 test_77c() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981         $GSS && skip_env "could not run with gss"
9982         remote_ost_nodsh && skip "remote OST with nodsh"
9983
9984         local bad1
9985         local osc_file_prefix
9986         local osc_file
9987         local check_ost=false
9988         local ost_file_prefix
9989         local ost_file
9990         local orig_cksum
9991         local dump_cksum
9992         local fid
9993
9994         # ensure corruption will occur on first OSS/OST
9995         $LFS setstripe -i 0 $DIR/$tfile
9996
9997         [ ! -f $F77_TMP ] && setup_f77
9998         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9999                 error "dd write error: $?"
10000         fid=$($LFS path2fid $DIR/$tfile)
10001
10002         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10003         then
10004                 check_ost=true
10005                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10006                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10007         else
10008                 echo "OSS do not support bulk pages dump upon error"
10009         fi
10010
10011         osc_file_prefix=$($LCTL get_param -n debug_path)
10012         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10013
10014         trap cleanup_77c EXIT
10015
10016         set_checksums 1
10017         # enable bulk pages dump upon error on Client
10018         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10019         # enable bulk pages dump upon error on OSS
10020         $check_ost &&
10021                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10022
10023         # flush Client cache to allow next read to reach OSS
10024         cancel_lru_locks osc
10025
10026         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10027         $LCTL set_param fail_loc=0x80000408
10028         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10029         $LCTL set_param fail_loc=0
10030
10031         rm -f $DIR/$tfile
10032
10033         # check cksum dump on Client
10034         osc_file=$(ls ${osc_file_prefix}*)
10035         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10036         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10037         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10038         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10039         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10040                      cksum)
10041         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10042         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10043                 error "dump content does not match on Client"
10044
10045         $check_ost || skip "No need to check cksum dump on OSS"
10046
10047         # check cksum dump on OSS
10048         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10049         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10050         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10051         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10052         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10053                 error "dump content does not match on OSS"
10054
10055         cleanup_77c
10056 }
10057 run_test 77c "checksum error on client read with debug"
10058
10059 test_77d() { # bug 10889
10060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10061         $GSS && skip_env "could not run with gss"
10062
10063         stack_trap "rm -f $DIR/$tfile"
10064         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10065         $LCTL set_param fail_loc=0x80000409
10066         set_checksums 1
10067         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10068                 error "direct write: rc=$?"
10069         $LCTL set_param fail_loc=0
10070         set_checksums 0
10071
10072         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10073         $LCTL set_param fail_loc=0x80000408
10074         set_checksums 1
10075         cancel_lru_locks osc
10076         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10077                 error "direct read: rc=$?"
10078         $LCTL set_param fail_loc=0
10079         set_checksums 0
10080 }
10081 run_test 77d "checksum error on OST direct write, read"
10082
10083 test_77f() { # bug 10889
10084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10085         $GSS && skip_env "could not run with gss"
10086
10087         set_checksums 1
10088         stack_trap "rm -f $DIR/$tfile"
10089         for algo in $CKSUM_TYPES; do
10090                 cancel_lru_locks osc
10091                 set_checksum_type $algo
10092                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10093                 $LCTL set_param fail_loc=0x409
10094                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10095                         error "direct write succeeded"
10096                 $LCTL set_param fail_loc=0
10097         done
10098         set_checksum_type $ORIG_CSUM_TYPE
10099         set_checksums 0
10100 }
10101 run_test 77f "repeat checksum error on write (expect error)"
10102
10103 test_77g() { # bug 10889
10104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10105         $GSS && skip_env "could not run with gss"
10106         remote_ost_nodsh && skip "remote OST with nodsh"
10107
10108         [ ! -f $F77_TMP ] && setup_f77
10109
10110         local file=$DIR/$tfile
10111         stack_trap "rm -f $file" EXIT
10112
10113         $LFS setstripe -c 1 -i 0 $file
10114         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10115         do_facet ost1 lctl set_param fail_loc=0x8000021a
10116         set_checksums 1
10117         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10118                 error "write error: rc=$?"
10119         do_facet ost1 lctl set_param fail_loc=0
10120         set_checksums 0
10121
10122         cancel_lru_locks osc
10123         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10124         do_facet ost1 lctl set_param fail_loc=0x8000021b
10125         set_checksums 1
10126         cmp $F77_TMP $file || error "file compare failed"
10127         do_facet ost1 lctl set_param fail_loc=0
10128         set_checksums 0
10129 }
10130 run_test 77g "checksum error on OST write, read"
10131
10132 test_77k() { # LU-10906
10133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10134         $GSS && skip_env "could not run with gss"
10135
10136         local cksum_param="osc.$FSNAME*.checksums"
10137         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10138         local checksum
10139         local i
10140
10141         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10142         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10143         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10144
10145         for i in 0 1; do
10146                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10147                         error "failed to set checksum=$i on MGS"
10148                 wait_update $HOSTNAME "$get_checksum" $i
10149                 #remount
10150                 echo "remount client, checksum should be $i"
10151                 remount_client $MOUNT || error "failed to remount client"
10152                 checksum=$(eval $get_checksum)
10153                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10154         done
10155         # remove persistent param to avoid races with checksum mountopt below
10156         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10157                 error "failed to delete checksum on MGS"
10158
10159         for opt in "checksum" "nochecksum"; do
10160                 #remount with mount option
10161                 echo "remount client with option $opt, checksum should be $i"
10162                 umount_client $MOUNT || error "failed to umount client"
10163                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10164                         error "failed to mount client with option '$opt'"
10165                 checksum=$(eval $get_checksum)
10166                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10167                 i=$((i - 1))
10168         done
10169
10170         remount_client $MOUNT || error "failed to remount client"
10171 }
10172 run_test 77k "enable/disable checksum correctly"
10173
10174 test_77l() {
10175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10176         $GSS && skip_env "could not run with gss"
10177
10178         set_checksums 1
10179         stack_trap "set_checksums $ORIG_CSUM" EXIT
10180         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10181
10182         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10183
10184         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10185         for algo in $CKSUM_TYPES; do
10186                 set_checksum_type $algo || error "fail to set checksum type $algo"
10187                 osc_algo=$(get_osc_checksum_type OST0000)
10188                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10189
10190                 # no locks, no reqs to let the connection idle
10191                 cancel_lru_locks osc
10192                 lru_resize_disable osc
10193                 wait_osc_import_state client ost1 IDLE
10194
10195                 # ensure ost1 is connected
10196                 stat $DIR/$tfile >/dev/null || error "can't stat"
10197                 wait_osc_import_state client ost1 FULL
10198
10199                 osc_algo=$(get_osc_checksum_type OST0000)
10200                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10201         done
10202         return 0
10203 }
10204 run_test 77l "preferred checksum type is remembered after reconnected"
10205
10206 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10207 rm -f $F77_TMP
10208 unset F77_TMP
10209
10210 test_77m() {
10211         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10212                 skip "Need at least version 2.14.52"
10213         local param=checksum_speed
10214
10215         $LCTL get_param $param || error "reading $param failed"
10216
10217         csum_speeds=$($LCTL get_param -n $param)
10218
10219         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10220                 error "known checksum types are missing"
10221 }
10222 run_test 77m "Verify checksum_speed is correctly read"
10223
10224 check_filefrag_77n() {
10225         local nr_ext=0
10226         local starts=()
10227         local ends=()
10228
10229         while read extidx a b start end rest; do
10230                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10231                         nr_ext=$(( $nr_ext + 1 ))
10232                         starts+=( ${start%..} )
10233                         ends+=( ${end%:} )
10234                 fi
10235         done < <( filefrag -sv $1 )
10236
10237         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10238         return 1
10239 }
10240
10241 test_77n() {
10242         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10243
10244         touch $DIR/$tfile
10245         $TRUNCATE $DIR/$tfile 0
10246         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10247         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10248         check_filefrag_77n $DIR/$tfile ||
10249                 skip "$tfile blocks not contiguous around hole"
10250
10251         set_checksums 1
10252         stack_trap "set_checksums $ORIG_CSUM" EXIT
10253         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10254         stack_trap "rm -f $DIR/$tfile"
10255
10256         for algo in $CKSUM_TYPES; do
10257                 if [[ "$algo" =~ ^t10 ]]; then
10258                         set_checksum_type $algo ||
10259                                 error "fail to set checksum type $algo"
10260                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10261                                 error "fail to read $tfile with $algo"
10262                 fi
10263         done
10264         rm -f $DIR/$tfile
10265         return 0
10266 }
10267 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10268
10269 test_77o() {
10270         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10271                 skip "Need MDS version at least 2.14.55"
10272         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10273                 skip "Need OST version at least 2.14.55"
10274         local ofd=obdfilter
10275         local mdt=mdt
10276
10277         # print OST checksum_type
10278         echo "$ofd.$FSNAME-*.checksum_type:"
10279         do_nodes $(comma_list $(osts_nodes)) \
10280                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10281
10282         # print MDT checksum_type
10283         echo "$mdt.$FSNAME-*.checksum_type:"
10284         do_nodes $(comma_list $(mdts_nodes)) \
10285                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10286
10287         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10288                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10289
10290         (( $o_count == $OSTCOUNT )) ||
10291                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10292
10293         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10294                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10295
10296         (( $m_count == $MDSCOUNT )) ||
10297                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10298 }
10299 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10300
10301 cleanup_test_78() {
10302         trap 0
10303         rm -f $DIR/$tfile
10304 }
10305
10306 test_78() { # bug 10901
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308         remote_ost || skip_env "local OST"
10309
10310         NSEQ=5
10311         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10312         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10313         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10314         echo "MemTotal: $MEMTOTAL"
10315
10316         # reserve 256MB of memory for the kernel and other running processes,
10317         # and then take 1/2 of the remaining memory for the read/write buffers.
10318         if [ $MEMTOTAL -gt 512 ] ;then
10319                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10320         else
10321                 # for those poor memory-starved high-end clusters...
10322                 MEMTOTAL=$((MEMTOTAL / 2))
10323         fi
10324         echo "Mem to use for directio: $MEMTOTAL"
10325
10326         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10327         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10328         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10329         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10330                 head -n1)
10331         echo "Smallest OST: $SMALLESTOST"
10332         [[ $SMALLESTOST -lt 10240 ]] &&
10333                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10334
10335         trap cleanup_test_78 EXIT
10336
10337         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10338                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10339
10340         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10341         echo "File size: $F78SIZE"
10342         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10343         for i in $(seq 1 $NSEQ); do
10344                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10345                 echo directIO rdwr round $i of $NSEQ
10346                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10347         done
10348
10349         cleanup_test_78
10350 }
10351 run_test 78 "handle large O_DIRECT writes correctly ============"
10352
10353 test_79() { # bug 12743
10354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10355
10356         wait_delete_completed
10357
10358         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10359         BKFREE=$(calc_osc_kbytes kbytesfree)
10360         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10361
10362         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10363         DFTOTAL=`echo $STRING | cut -d, -f1`
10364         DFUSED=`echo $STRING  | cut -d, -f2`
10365         DFAVAIL=`echo $STRING | cut -d, -f3`
10366         DFFREE=$(($DFTOTAL - $DFUSED))
10367
10368         ALLOWANCE=$((64 * $OSTCOUNT))
10369
10370         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10371            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10372                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10373         fi
10374         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10375            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10376                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10377         fi
10378         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10379            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10380                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10381         fi
10382 }
10383 run_test 79 "df report consistency check ======================="
10384
10385 test_80() { # bug 10718
10386         remote_ost_nodsh && skip "remote OST with nodsh"
10387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10388
10389         # relax strong synchronous semantics for slow backends like ZFS
10390         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10391                 local soc="obdfilter.*.sync_lock_cancel"
10392                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10393
10394                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10395                 if [ -z "$save" ]; then
10396                         soc="obdfilter.*.sync_on_lock_cancel"
10397                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10398                 fi
10399
10400                 if [ "$save" != "never" ]; then
10401                         local hosts=$(comma_list $(osts_nodes))
10402
10403                         do_nodes $hosts $LCTL set_param $soc=never
10404                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10405                 fi
10406         fi
10407
10408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10409         sync; sleep 1; sync
10410         local before=$(date +%s)
10411         cancel_lru_locks osc
10412         local after=$(date +%s)
10413         local diff=$((after - before))
10414         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10415
10416         rm -f $DIR/$tfile
10417 }
10418 run_test 80 "Page eviction is equally fast at high offsets too"
10419
10420 test_81a() { # LU-456
10421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10422         remote_ost_nodsh && skip "remote OST with nodsh"
10423
10424         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10425         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10426         do_facet ost1 lctl set_param fail_loc=0x80000228
10427
10428         # write should trigger a retry and success
10429         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10430         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10431         RC=$?
10432         if [ $RC -ne 0 ] ; then
10433                 error "write should success, but failed for $RC"
10434         fi
10435 }
10436 run_test 81a "OST should retry write when get -ENOSPC ==============="
10437
10438 test_81b() { # LU-456
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440         remote_ost_nodsh && skip "remote OST with nodsh"
10441
10442         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10443         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10444         do_facet ost1 lctl set_param fail_loc=0x228
10445
10446         # write should retry several times and return -ENOSPC finally
10447         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10449         RC=$?
10450         ENOSPC=28
10451         if [ $RC -ne $ENOSPC ] ; then
10452                 error "dd should fail for -ENOSPC, but succeed."
10453         fi
10454 }
10455 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10456
10457 test_99() {
10458         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10459
10460         test_mkdir $DIR/$tdir.cvsroot
10461         chown $RUNAS_ID $DIR/$tdir.cvsroot
10462
10463         cd $TMP
10464         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10465
10466         cd /etc/init.d
10467         # some versions of cvs import exit(1) when asked to import links or
10468         # files they can't read.  ignore those files.
10469         local toignore=$(find . -type l -printf '-I %f\n' -o \
10470                          ! -perm /4 -printf '-I %f\n')
10471         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10472                 $tdir.reposname vtag rtag
10473
10474         cd $DIR
10475         test_mkdir $DIR/$tdir.reposname
10476         chown $RUNAS_ID $DIR/$tdir.reposname
10477         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10478
10479         cd $DIR/$tdir.reposname
10480         $RUNAS touch foo99
10481         $RUNAS cvs add -m 'addmsg' foo99
10482         $RUNAS cvs update
10483         $RUNAS cvs commit -m 'nomsg' foo99
10484         rm -fr $DIR/$tdir.cvsroot
10485 }
10486 run_test 99 "cvs strange file/directory operations"
10487
10488 test_100() {
10489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10490         [[ "$NETTYPE" =~ tcp ]] ||
10491                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10492         remote_ost_nodsh && skip "remote OST with nodsh"
10493         remote_mds_nodsh && skip "remote MDS with nodsh"
10494         remote_servers ||
10495                 skip "useless for local single node setup"
10496
10497         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10498                 [ "$PROT" != "tcp" ] && continue
10499                 RPORT=$(echo $REMOTE | cut -d: -f2)
10500                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10501
10502                 rc=0
10503                 LPORT=`echo $LOCAL | cut -d: -f2`
10504                 if [ $LPORT -ge 1024 ]; then
10505                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10506                         netstat -tna
10507                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10508                 fi
10509         done
10510         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10511 }
10512 run_test 100 "check local port using privileged port ==========="
10513
10514 function get_named_value()
10515 {
10516     local tag=$1
10517
10518     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10519 }
10520
10521 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10522                    awk '/^max_cached_mb/ { print $2 }')
10523
10524 cleanup_101a() {
10525         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10526         trap 0
10527 }
10528
10529 test_101a() {
10530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10531
10532         local s
10533         local discard
10534         local nreads=10000
10535         local cache_limit=32
10536
10537         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10538         trap cleanup_101a EXIT
10539         $LCTL set_param -n llite.*.read_ahead_stats=0
10540         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10541
10542         #
10543         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10544         #
10545         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10546         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10547
10548         discard=0
10549         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10550                    get_named_value 'read.but.discarded'); do
10551                         discard=$(($discard + $s))
10552         done
10553         cleanup_101a
10554
10555         $LCTL get_param osc.*-osc*.rpc_stats
10556         $LCTL get_param llite.*.read_ahead_stats
10557
10558         # Discard is generally zero, but sometimes a few random reads line up
10559         # and trigger larger readahead, which is wasted & leads to discards.
10560         if [[ $(($discard)) -gt $nreads ]]; then
10561                 error "too many ($discard) discarded pages"
10562         fi
10563         rm -f $DIR/$tfile || true
10564 }
10565 run_test 101a "check read-ahead for random reads"
10566
10567 setup_test101bc() {
10568         test_mkdir $DIR/$tdir
10569         local ssize=$1
10570         local FILE_LENGTH=$2
10571         STRIPE_OFFSET=0
10572
10573         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10574
10575         local list=$(comma_list $(osts_nodes))
10576         set_osd_param $list '' read_cache_enable 0
10577         set_osd_param $list '' writethrough_cache_enable 0
10578
10579         trap cleanup_test101bc EXIT
10580         # prepare the read-ahead file
10581         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10582
10583         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10584                                 count=$FILE_SIZE_MB 2> /dev/null
10585
10586 }
10587
10588 cleanup_test101bc() {
10589         trap 0
10590         rm -rf $DIR/$tdir
10591         rm -f $DIR/$tfile
10592
10593         local list=$(comma_list $(osts_nodes))
10594         set_osd_param $list '' read_cache_enable 1
10595         set_osd_param $list '' writethrough_cache_enable 1
10596 }
10597
10598 calc_total() {
10599         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10600 }
10601
10602 ra_check_101() {
10603         local read_size=$1
10604         local stripe_size=$2
10605         local stride_length=$((stripe_size / read_size))
10606         local stride_width=$((stride_length * OSTCOUNT))
10607         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10608                                 (stride_width - stride_length) ))
10609         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10610                   get_named_value 'read.but.discarded' | calc_total)
10611
10612         if [[ $discard -gt $discard_limit ]]; then
10613                 $LCTL get_param llite.*.read_ahead_stats
10614                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10615         else
10616                 echo "Read-ahead success for size ${read_size}"
10617         fi
10618 }
10619
10620 test_101b() {
10621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10623
10624         local STRIPE_SIZE=1048576
10625         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10626
10627         if [ $SLOW == "yes" ]; then
10628                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10629         else
10630                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10631         fi
10632
10633         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10634
10635         # prepare the read-ahead file
10636         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10637         cancel_lru_locks osc
10638         for BIDX in 2 4 8 16 32 64 128 256
10639         do
10640                 local BSIZE=$((BIDX*4096))
10641                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10642                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10643                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10644                 $LCTL set_param -n llite.*.read_ahead_stats=0
10645                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10646                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10647                 cancel_lru_locks osc
10648                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10649         done
10650         cleanup_test101bc
10651         true
10652 }
10653 run_test 101b "check stride-io mode read-ahead ================="
10654
10655 test_101c() {
10656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10657
10658         local STRIPE_SIZE=1048576
10659         local FILE_LENGTH=$((STRIPE_SIZE*100))
10660         local nreads=10000
10661         local rsize=65536
10662         local osc_rpc_stats
10663
10664         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10665
10666         cancel_lru_locks osc
10667         $LCTL set_param osc.*.rpc_stats=0
10668         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10669         $LCTL get_param osc.*.rpc_stats
10670         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10671                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10672                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10673                 local size
10674
10675                 if [ $lines -le 20 ]; then
10676                         echo "continue debug"
10677                         continue
10678                 fi
10679                 for size in 1 2 4 8; do
10680                         local rpc=$(echo "$stats" |
10681                                     awk '($1 == "'$size':") {print $2; exit; }')
10682                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10683                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10684                 done
10685                 echo "$osc_rpc_stats check passed!"
10686         done
10687         cleanup_test101bc
10688         true
10689 }
10690 run_test 101c "check stripe_size aligned read-ahead"
10691
10692 test_101d() {
10693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10694
10695         local file=$DIR/$tfile
10696         local sz_MB=${FILESIZE_101d:-80}
10697         local ra_MB=${READAHEAD_MB:-40}
10698
10699         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10700         [ $free_MB -lt $sz_MB ] &&
10701                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10702
10703         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10704         $LFS setstripe -c -1 $file || error "setstripe failed"
10705
10706         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10707         echo Cancel LRU locks on lustre client to flush the client cache
10708         cancel_lru_locks osc
10709
10710         echo Disable read-ahead
10711         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10712         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10713         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10714         $LCTL get_param -n llite.*.max_read_ahead_mb
10715
10716         echo "Reading the test file $file with read-ahead disabled"
10717         local sz_KB=$((sz_MB * 1024 / 4))
10718         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10719         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10720         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10721                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10722
10723         echo "Cancel LRU locks on lustre client to flush the client cache"
10724         cancel_lru_locks osc
10725         echo Enable read-ahead with ${ra_MB}MB
10726         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10727
10728         echo "Reading the test file $file with read-ahead enabled"
10729         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10730                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10731
10732         echo "read-ahead disabled time read $raOFF"
10733         echo "read-ahead enabled time read $raON"
10734
10735         rm -f $file
10736         wait_delete_completed
10737
10738         # use awk for this check instead of bash because it handles decimals
10739         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10740                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10741 }
10742 run_test 101d "file read with and without read-ahead enabled"
10743
10744 test_101e() {
10745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10746
10747         local file=$DIR/$tfile
10748         local size_KB=500  #KB
10749         local count=100
10750         local bsize=1024
10751
10752         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10753         local need_KB=$((count * size_KB))
10754         [[ $free_KB -le $need_KB ]] &&
10755                 skip_env "Need free space $need_KB, have $free_KB"
10756
10757         echo "Creating $count ${size_KB}K test files"
10758         for ((i = 0; i < $count; i++)); do
10759                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10760         done
10761
10762         echo "Cancel LRU locks on lustre client to flush the client cache"
10763         cancel_lru_locks $OSC
10764
10765         echo "Reset readahead stats"
10766         $LCTL set_param -n llite.*.read_ahead_stats=0
10767
10768         for ((i = 0; i < $count; i++)); do
10769                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10770         done
10771
10772         $LCTL get_param llite.*.max_cached_mb
10773         $LCTL get_param llite.*.read_ahead_stats
10774         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10775                      get_named_value 'misses' | calc_total)
10776
10777         for ((i = 0; i < $count; i++)); do
10778                 rm -rf $file.$i 2>/dev/null
10779         done
10780
10781         #10000 means 20% reads are missing in readahead
10782         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10783 }
10784 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10785
10786 test_101f() {
10787         which iozone || skip_env "no iozone installed"
10788
10789         local old_debug=$($LCTL get_param debug)
10790         old_debug=${old_debug#*=}
10791         $LCTL set_param debug="reada mmap"
10792
10793         # create a test file
10794         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10795
10796         echo Cancel LRU locks on lustre client to flush the client cache
10797         cancel_lru_locks osc
10798
10799         echo Reset readahead stats
10800         $LCTL set_param -n llite.*.read_ahead_stats=0
10801
10802         echo mmap read the file with small block size
10803         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10804                 > /dev/null 2>&1
10805
10806         echo checking missing pages
10807         $LCTL get_param llite.*.read_ahead_stats
10808         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10809                         get_named_value 'misses' | calc_total)
10810
10811         $LCTL set_param debug="$old_debug"
10812         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10813         rm -f $DIR/$tfile
10814 }
10815 run_test 101f "check mmap read performance"
10816
10817 test_101g_brw_size_test() {
10818         local mb=$1
10819         local pages=$((mb * 1048576 / PAGE_SIZE))
10820         local file=$DIR/$tfile
10821
10822         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10823                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10824         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10825                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10826                         return 2
10827         done
10828
10829         stack_trap "rm -f $file" EXIT
10830         $LCTL set_param -n osc.*.rpc_stats=0
10831
10832         # 10 RPCs should be enough for the test
10833         local count=10
10834         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10835                 { error "dd write ${mb} MB blocks failed"; return 3; }
10836         cancel_lru_locks osc
10837         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10838                 { error "dd write ${mb} MB blocks failed"; return 4; }
10839
10840         # calculate number of full-sized read and write RPCs
10841         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10842                 sed -n '/pages per rpc/,/^$/p' |
10843                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10844                 END { print reads,writes }'))
10845         # allow one extra full-sized read RPC for async readahead
10846         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10847                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10848         [[ ${rpcs[1]} == $count ]] ||
10849                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10850 }
10851
10852 test_101g() {
10853         remote_ost_nodsh && skip "remote OST with nodsh"
10854
10855         local rpcs
10856         local osts=$(get_facets OST)
10857         local list=$(comma_list $(osts_nodes))
10858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10859         local brw_size="obdfilter.*.brw_size"
10860
10861         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10862
10863         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10864
10865         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10866                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10867                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10868            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10869                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10870                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10871
10872                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10873                         suffix="M"
10874
10875                 if [[ $orig_mb -lt 16 ]]; then
10876                         save_lustre_params $osts "$brw_size" > $p
10877                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10878                                 error "set 16MB RPC size failed"
10879
10880                         echo "remount client to enable new RPC size"
10881                         remount_client $MOUNT || error "remount_client failed"
10882                 fi
10883
10884                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10885                 # should be able to set brw_size=12, but no rpc_stats for that
10886                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10887         fi
10888
10889         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10890
10891         if [[ $orig_mb -lt 16 ]]; then
10892                 restore_lustre_params < $p
10893                 remount_client $MOUNT || error "remount_client restore failed"
10894         fi
10895
10896         rm -f $p $DIR/$tfile
10897 }
10898 run_test 101g "Big bulk(4/16 MiB) readahead"
10899
10900 test_101h() {
10901         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10902
10903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10904                 error "dd 70M file failed"
10905         echo Cancel LRU locks on lustre client to flush the client cache
10906         cancel_lru_locks osc
10907
10908         echo "Reset readahead stats"
10909         $LCTL set_param -n llite.*.read_ahead_stats 0
10910
10911         echo "Read 10M of data but cross 64M bundary"
10912         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10913         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10914                      get_named_value 'misses' | calc_total)
10915         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10916         rm -f $p $DIR/$tfile
10917 }
10918 run_test 101h "Readahead should cover current read window"
10919
10920 test_101i() {
10921         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10922                 error "dd 10M file failed"
10923
10924         local max_per_file_mb=$($LCTL get_param -n \
10925                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10926         cancel_lru_locks osc
10927         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10928         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10929                 error "set max_read_ahead_per_file_mb to 1 failed"
10930
10931         echo "Reset readahead stats"
10932         $LCTL set_param llite.*.read_ahead_stats=0
10933
10934         dd if=$DIR/$tfile of=/dev/null bs=2M
10935
10936         $LCTL get_param llite.*.read_ahead_stats
10937         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10938                      awk '/misses/ { print $2 }')
10939         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10940         rm -f $DIR/$tfile
10941 }
10942 run_test 101i "allow current readahead to exceed reservation"
10943
10944 test_101j() {
10945         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10946                 error "setstripe $DIR/$tfile failed"
10947         local file_size=$((1048576 * 16))
10948         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10949         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10950
10951         echo Disable read-ahead
10952         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10953
10954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10955         for blk in $PAGE_SIZE 1048576 $file_size; do
10956                 cancel_lru_locks osc
10957                 echo "Reset readahead stats"
10958                 $LCTL set_param -n llite.*.read_ahead_stats=0
10959                 local count=$(($file_size / $blk))
10960                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10961                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10962                              get_named_value 'failed.to.fast.read' | calc_total)
10963                 $LCTL get_param -n llite.*.read_ahead_stats
10964                 [ $miss -eq $count ] || error "expected $count got $miss"
10965         done
10966
10967         rm -f $p $DIR/$tfile
10968 }
10969 run_test 101j "A complete read block should be submitted when no RA"
10970
10971 setup_test102() {
10972         test_mkdir $DIR/$tdir
10973         chown $RUNAS_ID $DIR/$tdir
10974         STRIPE_SIZE=65536
10975         STRIPE_OFFSET=1
10976         STRIPE_COUNT=$OSTCOUNT
10977         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10978
10979         trap cleanup_test102 EXIT
10980         cd $DIR
10981         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10982         cd $DIR/$tdir
10983         for num in 1 2 3 4; do
10984                 for count in $(seq 1 $STRIPE_COUNT); do
10985                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10986                                 local size=`expr $STRIPE_SIZE \* $num`
10987                                 local file=file"$num-$idx-$count"
10988                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10989                         done
10990                 done
10991         done
10992
10993         cd $DIR
10994         $1 tar cf $TMP/f102.tar $tdir --xattrs
10995 }
10996
10997 cleanup_test102() {
10998         trap 0
10999         rm -f $TMP/f102.tar
11000         rm -rf $DIR/d0.sanity/d102
11001 }
11002
11003 test_102a() {
11004         [ "$UID" != 0 ] && skip "must run as root"
11005         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11006                 skip_env "must have user_xattr"
11007
11008         [ -z "$(which setfattr 2>/dev/null)" ] &&
11009                 skip_env "could not find setfattr"
11010
11011         local testfile=$DIR/$tfile
11012
11013         touch $testfile
11014         echo "set/get xattr..."
11015         setfattr -n trusted.name1 -v value1 $testfile ||
11016                 error "setfattr -n trusted.name1=value1 $testfile failed"
11017         getfattr -n trusted.name1 $testfile 2> /dev/null |
11018           grep "trusted.name1=.value1" ||
11019                 error "$testfile missing trusted.name1=value1"
11020
11021         setfattr -n user.author1 -v author1 $testfile ||
11022                 error "setfattr -n user.author1=author1 $testfile failed"
11023         getfattr -n user.author1 $testfile 2> /dev/null |
11024           grep "user.author1=.author1" ||
11025                 error "$testfile missing trusted.author1=author1"
11026
11027         echo "listxattr..."
11028         setfattr -n trusted.name2 -v value2 $testfile ||
11029                 error "$testfile unable to set trusted.name2"
11030         setfattr -n trusted.name3 -v value3 $testfile ||
11031                 error "$testfile unable to set trusted.name3"
11032         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11033             grep "trusted.name" | wc -l) -eq 3 ] ||
11034                 error "$testfile missing 3 trusted.name xattrs"
11035
11036         setfattr -n user.author2 -v author2 $testfile ||
11037                 error "$testfile unable to set user.author2"
11038         setfattr -n user.author3 -v author3 $testfile ||
11039                 error "$testfile unable to set user.author3"
11040         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11041             grep "user.author" | wc -l) -eq 3 ] ||
11042                 error "$testfile missing 3 user.author xattrs"
11043
11044         echo "remove xattr..."
11045         setfattr -x trusted.name1 $testfile ||
11046                 error "$testfile error deleting trusted.name1"
11047         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11048                 error "$testfile did not delete trusted.name1 xattr"
11049
11050         setfattr -x user.author1 $testfile ||
11051                 error "$testfile error deleting user.author1"
11052         echo "set lustre special xattr ..."
11053         $LFS setstripe -c1 $testfile
11054         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11055                 awk -F "=" '/trusted.lov/ { print $2 }' )
11056         setfattr -n "trusted.lov" -v $lovea $testfile ||
11057                 error "$testfile doesn't ignore setting trusted.lov again"
11058         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11059                 error "$testfile allow setting invalid trusted.lov"
11060         rm -f $testfile
11061 }
11062 run_test 102a "user xattr test =================================="
11063
11064 check_102b_layout() {
11065         local layout="$*"
11066         local testfile=$DIR/$tfile
11067
11068         echo "test layout '$layout'"
11069         $LFS setstripe $layout $testfile || error "setstripe failed"
11070         $LFS getstripe -y $testfile
11071
11072         echo "get/set/list trusted.lov xattr ..." # b=10930
11073         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11074         [[ "$value" =~ "trusted.lov" ]] ||
11075                 error "can't get trusted.lov from $testfile"
11076         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11077                 error "getstripe failed"
11078
11079         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11080
11081         value=$(cut -d= -f2 <<<$value)
11082         # LU-13168: truncated xattr should fail if short lov_user_md header
11083         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11084                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11085         for len in $lens; do
11086                 echo "setfattr $len $testfile.2"
11087                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11088                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11089         done
11090         local stripe_size=$($LFS getstripe -S $testfile.2)
11091         local stripe_count=$($LFS getstripe -c $testfile.2)
11092         [[ $stripe_size -eq 65536 ]] ||
11093                 error "stripe size $stripe_size != 65536"
11094         [[ $stripe_count -eq $stripe_count_orig ]] ||
11095                 error "stripe count $stripe_count != $stripe_count_orig"
11096         rm $testfile $testfile.2
11097 }
11098
11099 test_102b() {
11100         [ -z "$(which setfattr 2>/dev/null)" ] &&
11101                 skip_env "could not find setfattr"
11102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11103
11104         # check plain layout
11105         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11106
11107         # and also check composite layout
11108         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11109
11110 }
11111 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11112
11113 test_102c() {
11114         [ -z "$(which setfattr 2>/dev/null)" ] &&
11115                 skip_env "could not find setfattr"
11116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11117
11118         # b10930: get/set/list lustre.lov xattr
11119         echo "get/set/list lustre.lov xattr ..."
11120         test_mkdir $DIR/$tdir
11121         chown $RUNAS_ID $DIR/$tdir
11122         local testfile=$DIR/$tdir/$tfile
11123         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11124                 error "setstripe failed"
11125         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11126                 error "getstripe failed"
11127         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11128         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11129
11130         local testfile2=${testfile}2
11131         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11132                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11133
11134         $RUNAS $MCREATE $testfile2
11135         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11136         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11137         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11138         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11139         [ $stripe_count -eq $STRIPECOUNT ] ||
11140                 error "stripe count $stripe_count != $STRIPECOUNT"
11141 }
11142 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11143
11144 compare_stripe_info1() {
11145         local stripe_index_all_zero=true
11146
11147         for num in 1 2 3 4; do
11148                 for count in $(seq 1 $STRIPE_COUNT); do
11149                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11150                                 local size=$((STRIPE_SIZE * num))
11151                                 local file=file"$num-$offset-$count"
11152                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11153                                 [[ $stripe_size -ne $size ]] &&
11154                                     error "$file: size $stripe_size != $size"
11155                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11156                                 # allow fewer stripes to be created, ORI-601
11157                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11158                                     error "$file: count $stripe_count != $count"
11159                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11160                                 [[ $stripe_index -ne 0 ]] &&
11161                                         stripe_index_all_zero=false
11162                         done
11163                 done
11164         done
11165         $stripe_index_all_zero &&
11166                 error "all files are being extracted starting from OST index 0"
11167         return 0
11168 }
11169
11170 have_xattrs_include() {
11171         tar --help | grep -q xattrs-include &&
11172                 echo --xattrs-include="lustre.*"
11173 }
11174
11175 test_102d() {
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11178
11179         XINC=$(have_xattrs_include)
11180         setup_test102
11181         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11182         cd $DIR/$tdir/$tdir
11183         compare_stripe_info1
11184 }
11185 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11186
11187 test_102f() {
11188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11190
11191         XINC=$(have_xattrs_include)
11192         setup_test102
11193         test_mkdir $DIR/$tdir.restore
11194         cd $DIR
11195         tar cf - --xattrs $tdir | tar xf - \
11196                 -C $DIR/$tdir.restore --xattrs $XINC
11197         cd $DIR/$tdir.restore/$tdir
11198         compare_stripe_info1
11199 }
11200 run_test 102f "tar copy files, not keep osts"
11201
11202 grow_xattr() {
11203         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11204                 skip "must have user_xattr"
11205         [ -z "$(which setfattr 2>/dev/null)" ] &&
11206                 skip_env "could not find setfattr"
11207         [ -z "$(which getfattr 2>/dev/null)" ] &&
11208                 skip_env "could not find getfattr"
11209
11210         local xsize=${1:-1024}  # in bytes
11211         local file=$DIR/$tfile
11212         local value="$(generate_string $xsize)"
11213         local xbig=trusted.big
11214         local toobig=$2
11215
11216         touch $file
11217         log "save $xbig on $file"
11218         if [ -z "$toobig" ]
11219         then
11220                 setfattr -n $xbig -v $value $file ||
11221                         error "saving $xbig on $file failed"
11222         else
11223                 setfattr -n $xbig -v $value $file &&
11224                         error "saving $xbig on $file succeeded"
11225                 return 0
11226         fi
11227
11228         local orig=$(get_xattr_value $xbig $file)
11229         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11230
11231         local xsml=trusted.sml
11232         log "save $xsml on $file"
11233         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11234
11235         local new=$(get_xattr_value $xbig $file)
11236         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11237
11238         log "grow $xsml on $file"
11239         setfattr -n $xsml -v "$value" $file ||
11240                 error "growing $xsml on $file failed"
11241
11242         new=$(get_xattr_value $xbig $file)
11243         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11244         log "$xbig still valid after growing $xsml"
11245
11246         rm -f $file
11247 }
11248
11249 test_102h() { # bug 15777
11250         grow_xattr 1024
11251 }
11252 run_test 102h "grow xattr from inside inode to external block"
11253
11254 test_102ha() {
11255         large_xattr_enabled || skip_env "ea_inode feature disabled"
11256
11257         echo "setting xattr of max xattr size: $(max_xattr_size)"
11258         grow_xattr $(max_xattr_size)
11259
11260         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11261         echo "This should fail:"
11262         grow_xattr $(($(max_xattr_size) + 10)) 1
11263 }
11264 run_test 102ha "grow xattr from inside inode to external inode"
11265
11266 test_102i() { # bug 17038
11267         [ -z "$(which getfattr 2>/dev/null)" ] &&
11268                 skip "could not find getfattr"
11269
11270         touch $DIR/$tfile
11271         ln -s $DIR/$tfile $DIR/${tfile}link
11272         getfattr -n trusted.lov $DIR/$tfile ||
11273                 error "lgetxattr on $DIR/$tfile failed"
11274         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11275                 grep -i "no such attr" ||
11276                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11277         rm -f $DIR/$tfile $DIR/${tfile}link
11278 }
11279 run_test 102i "lgetxattr test on symbolic link ============"
11280
11281 test_102j() {
11282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11283         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11284
11285         XINC=$(have_xattrs_include)
11286         setup_test102 "$RUNAS"
11287         chown $RUNAS_ID $DIR/$tdir
11288         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11289         cd $DIR/$tdir/$tdir
11290         compare_stripe_info1 "$RUNAS"
11291 }
11292 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11293
11294 test_102k() {
11295         [ -z "$(which setfattr 2>/dev/null)" ] &&
11296                 skip "could not find setfattr"
11297
11298         touch $DIR/$tfile
11299         # b22187 just check that does not crash for regular file.
11300         setfattr -n trusted.lov $DIR/$tfile
11301         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11302         local test_kdir=$DIR/$tdir
11303         test_mkdir $test_kdir
11304         local default_size=$($LFS getstripe -S $test_kdir)
11305         local default_count=$($LFS getstripe -c $test_kdir)
11306         local default_offset=$($LFS getstripe -i $test_kdir)
11307         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11308                 error 'dir setstripe failed'
11309         setfattr -n trusted.lov $test_kdir
11310         local stripe_size=$($LFS getstripe -S $test_kdir)
11311         local stripe_count=$($LFS getstripe -c $test_kdir)
11312         local stripe_offset=$($LFS getstripe -i $test_kdir)
11313         [ $stripe_size -eq $default_size ] ||
11314                 error "stripe size $stripe_size != $default_size"
11315         [ $stripe_count -eq $default_count ] ||
11316                 error "stripe count $stripe_count != $default_count"
11317         [ $stripe_offset -eq $default_offset ] ||
11318                 error "stripe offset $stripe_offset != $default_offset"
11319         rm -rf $DIR/$tfile $test_kdir
11320 }
11321 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11322
11323 test_102l() {
11324         [ -z "$(which getfattr 2>/dev/null)" ] &&
11325                 skip "could not find getfattr"
11326
11327         # LU-532 trusted. xattr is invisible to non-root
11328         local testfile=$DIR/$tfile
11329
11330         touch $testfile
11331
11332         echo "listxattr as user..."
11333         chown $RUNAS_ID $testfile
11334         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11335             grep -q "trusted" &&
11336                 error "$testfile trusted xattrs are user visible"
11337
11338         return 0;
11339 }
11340 run_test 102l "listxattr size test =================================="
11341
11342 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11343         local path=$DIR/$tfile
11344         touch $path
11345
11346         listxattr_size_check $path || error "listattr_size_check $path failed"
11347 }
11348 run_test 102m "Ensure listxattr fails on small bufffer ========"
11349
11350 cleanup_test102
11351
11352 getxattr() { # getxattr path name
11353         # Return the base64 encoding of the value of xattr name on path.
11354         local path=$1
11355         local name=$2
11356
11357         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11358         # file: $path
11359         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11360         #
11361         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11362
11363         getfattr --absolute-names --encoding=base64 --name=$name $path |
11364                 awk -F= -v name=$name '$1 == name {
11365                         print substr($0, index($0, "=") + 1);
11366         }'
11367 }
11368
11369 test_102n() { # LU-4101 mdt: protect internal xattrs
11370         [ -z "$(which setfattr 2>/dev/null)" ] &&
11371                 skip "could not find setfattr"
11372         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11373         then
11374                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11375         fi
11376
11377         local file0=$DIR/$tfile.0
11378         local file1=$DIR/$tfile.1
11379         local xattr0=$TMP/$tfile.0
11380         local xattr1=$TMP/$tfile.1
11381         local namelist="lov lma lmv link fid version som hsm"
11382         local name
11383         local value
11384
11385         rm -rf $file0 $file1 $xattr0 $xattr1
11386         touch $file0 $file1
11387
11388         # Get 'before' xattrs of $file1.
11389         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11390
11391         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11392                 namelist+=" lfsck_namespace"
11393         for name in $namelist; do
11394                 # Try to copy xattr from $file0 to $file1.
11395                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11396
11397                 setfattr --name=trusted.$name --value="$value" $file1 ||
11398                         error "setxattr 'trusted.$name' failed"
11399
11400                 # Try to set a garbage xattr.
11401                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11402
11403                 if [[ x$name == "xlov" ]]; then
11404                         setfattr --name=trusted.lov --value="$value" $file1 &&
11405                         error "setxattr invalid 'trusted.lov' success"
11406                 else
11407                         setfattr --name=trusted.$name --value="$value" $file1 ||
11408                                 error "setxattr invalid 'trusted.$name' failed"
11409                 fi
11410
11411                 # Try to remove the xattr from $file1. We don't care if this
11412                 # appears to succeed or fail, we just don't want there to be
11413                 # any changes or crashes.
11414                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11415         done
11416
11417         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11418         then
11419                 name="lfsck_ns"
11420                 # Try to copy xattr from $file0 to $file1.
11421                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11422
11423                 setfattr --name=trusted.$name --value="$value" $file1 ||
11424                         error "setxattr 'trusted.$name' failed"
11425
11426                 # Try to set a garbage xattr.
11427                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11428
11429                 setfattr --name=trusted.$name --value="$value" $file1 ||
11430                         error "setxattr 'trusted.$name' failed"
11431
11432                 # Try to remove the xattr from $file1. We don't care if this
11433                 # appears to succeed or fail, we just don't want there to be
11434                 # any changes or crashes.
11435                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11436         fi
11437
11438         # Get 'after' xattrs of file1.
11439         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11440
11441         if ! diff $xattr0 $xattr1; then
11442                 error "before and after xattrs of '$file1' differ"
11443         fi
11444
11445         rm -rf $file0 $file1 $xattr0 $xattr1
11446
11447         return 0
11448 }
11449 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11450
11451 test_102p() { # LU-4703 setxattr did not check ownership
11452         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11453                 skip "MDS needs to be at least 2.5.56"
11454
11455         local testfile=$DIR/$tfile
11456
11457         touch $testfile
11458
11459         echo "setfacl as user..."
11460         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11461         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11462
11463         echo "setfattr as user..."
11464         setfacl -m "u:$RUNAS_ID:---" $testfile
11465         $RUNAS setfattr -x system.posix_acl_access $testfile
11466         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11467 }
11468 run_test 102p "check setxattr(2) correctly fails without permission"
11469
11470 test_102q() {
11471         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11472                 skip "MDS needs to be at least 2.6.92"
11473
11474         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11475 }
11476 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11477
11478 test_102r() {
11479         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11480                 skip "MDS needs to be at least 2.6.93"
11481
11482         touch $DIR/$tfile || error "touch"
11483         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11484         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11485         rm $DIR/$tfile || error "rm"
11486
11487         #normal directory
11488         mkdir -p $DIR/$tdir || error "mkdir"
11489         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11490         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11491         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11492                 error "$testfile error deleting user.author1"
11493         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11494                 grep "user.$(basename $tdir)" &&
11495                 error "$tdir did not delete user.$(basename $tdir)"
11496         rmdir $DIR/$tdir || error "rmdir"
11497
11498         #striped directory
11499         test_mkdir $DIR/$tdir
11500         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11501         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11502         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11503                 error "$testfile error deleting user.author1"
11504         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11505                 grep "user.$(basename $tdir)" &&
11506                 error "$tdir did not delete user.$(basename $tdir)"
11507         rmdir $DIR/$tdir || error "rm striped dir"
11508 }
11509 run_test 102r "set EAs with empty values"
11510
11511 test_102s() {
11512         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11513                 skip "MDS needs to be at least 2.11.52"
11514
11515         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11516
11517         save_lustre_params client "llite.*.xattr_cache" > $save
11518
11519         for cache in 0 1; do
11520                 lctl set_param llite.*.xattr_cache=$cache
11521
11522                 rm -f $DIR/$tfile
11523                 touch $DIR/$tfile || error "touch"
11524                 for prefix in lustre security system trusted user; do
11525                         # Note getxattr() may fail with 'Operation not
11526                         # supported' or 'No such attribute' depending
11527                         # on prefix and cache.
11528                         getfattr -n $prefix.n102s $DIR/$tfile &&
11529                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11530                 done
11531         done
11532
11533         restore_lustre_params < $save
11534 }
11535 run_test 102s "getting nonexistent xattrs should fail"
11536
11537 test_102t() {
11538         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11539                 skip "MDS needs to be at least 2.11.52"
11540
11541         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11542
11543         save_lustre_params client "llite.*.xattr_cache" > $save
11544
11545         for cache in 0 1; do
11546                 lctl set_param llite.*.xattr_cache=$cache
11547
11548                 for buf_size in 0 256; do
11549                         rm -f $DIR/$tfile
11550                         touch $DIR/$tfile || error "touch"
11551                         setfattr -n user.multiop $DIR/$tfile
11552                         $MULTIOP $DIR/$tfile oa$buf_size ||
11553                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11554                 done
11555         done
11556
11557         restore_lustre_params < $save
11558 }
11559 run_test 102t "zero length xattr values handled correctly"
11560
11561 run_acl_subtest()
11562 {
11563         local test=$LUSTRE/tests/acl/$1.test
11564         local tmp=$(mktemp -t $1-XXXXXX).test
11565         local bin=$2
11566         local dmn=$3
11567         local grp=$4
11568         local nbd=$5
11569         export LANG=C
11570
11571
11572         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11573         local sedgroups="-e s/:users/:$grp/g"
11574         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11575
11576         sed $sedusers $sedgroups < $test > $tmp
11577         stack_trap "rm -f $tmp"
11578         [[ -s $tmp ]] || error "sed failed to create test script"
11579
11580         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11581         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11582 }
11583
11584 test_103a() {
11585         [ "$UID" != 0 ] && skip "must run as root"
11586         $GSS && skip_env "could not run under gss"
11587         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11588                 skip_env "must have acl enabled"
11589         which setfacl || skip_env "could not find setfacl"
11590         remote_mds_nodsh && skip "remote MDS with nodsh"
11591
11592         ACLBIN=${ACLBIN:-"bin"}
11593         ACLDMN=${ACLDMN:-"daemon"}
11594         ACLGRP=${ACLGRP:-"users"}
11595         ACLNBD=${ACLNBD:-"nobody"}
11596
11597         if ! id $ACLBIN ||
11598            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11599                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11600                 ACLBIN=$USER0
11601                 if ! id $ACLBIN ; then
11602                         cat /etc/passwd
11603                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11604                 fi
11605         fi
11606         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11607            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11608                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11609                 ACLDMN=$USER1
11610                 if ! id $ACLDMN ; then
11611                         cat /etc/passwd
11612                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11613                 fi
11614         fi
11615         if ! getent group $ACLGRP; then
11616                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11617                 ACLGRP="$TSTUSR"
11618                 if ! getent group $ACLGRP; then
11619                         echo "cannot find group '$ACLGRP', adding it"
11620                         cat /etc/group
11621                         add_group 60000 $ACLGRP
11622                 fi
11623         fi
11624
11625         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11626         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11627         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11628
11629         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11630                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11631                 ACLGRP="$TSTUSR"
11632                 if ! getent group $ACLGRP; then
11633                         echo "cannot find group '$ACLGRP', adding it"
11634                         cat /etc/group
11635                         add_group 60000 $ACLGRP
11636                 fi
11637                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11638                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11639                         cat /etc/group
11640                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11641                 fi
11642         fi
11643
11644         gpasswd -a $ACLDMN $ACLBIN ||
11645                 error "setting client group failed"             # LU-5641
11646         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11647                 error "setting MDS group failed"                # LU-5641
11648
11649         declare -a identity_old
11650
11651         for num in $(seq $MDSCOUNT); do
11652                 switch_identity $num true || identity_old[$num]=$?
11653         done
11654
11655         SAVE_UMASK=$(umask)
11656         umask 0022
11657         mkdir -p $DIR/$tdir
11658         cd $DIR/$tdir
11659
11660         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11661         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11662         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11663         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11664         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11665         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11666         if ! id -u $ACLNBD ||
11667            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11668                 ACLNBD="nfsnobody"
11669                 if ! id -u $ACLNBD; then
11670                         ACLNBD=""
11671                 fi
11672         fi
11673         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11674                 add_group $(id -u $ACLNBD) $ACLNBD
11675                 if ! getent group $ACLNBD; then
11676                         ACLNBD=""
11677                 fi
11678         fi
11679         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11680            [[ -n "$ACLNBD" ]] && which setfattr; then
11681                 run_acl_subtest permissions_xattr \
11682                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11683         elif [[ -z "$ACLNBD" ]]; then
11684                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11685         else
11686                 echo "skip 'permission_xattr' test - missing setfattr command"
11687         fi
11688         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11689
11690         # inheritance test got from HP
11691         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11692         chmod +x make-tree || error "chmod +x failed"
11693         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11694         rm -f make-tree
11695
11696         echo "LU-974 ignore umask when acl is enabled..."
11697         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11698         if [ $MDSCOUNT -ge 2 ]; then
11699                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11700         fi
11701
11702         echo "LU-2561 newly created file is same size as directory..."
11703         if [ "$mds1_FSTYPE" != "zfs" ]; then
11704                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11705         else
11706                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11707         fi
11708
11709         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11710
11711         cd $SAVE_PWD
11712         umask $SAVE_UMASK
11713
11714         for num in $(seq $MDSCOUNT); do
11715                 if [ "${identity_old[$num]}" = 1 ]; then
11716                         switch_identity $num false || identity_old[$num]=$?
11717                 fi
11718         done
11719 }
11720 run_test 103a "acl test"
11721
11722 test_103b() {
11723         declare -a pids
11724         local U
11725
11726         for U in {0..511}; do
11727                 {
11728                 local O=$(printf "%04o" $U)
11729
11730                 umask $(printf "%04o" $((511 ^ $O)))
11731                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11732                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11733
11734                 (( $S == ($O & 0666) )) ||
11735                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11736
11737                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11738                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11739                 (( $S == ($O & 0666) )) ||
11740                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11741
11742                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11743                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11744                 (( $S == ($O & 0666) )) ||
11745                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11746                 rm -f $DIR/$tfile.[smp]$0
11747                 } &
11748                 local pid=$!
11749
11750                 # limit the concurrently running threads to 64. LU-11878
11751                 local idx=$((U % 64))
11752                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11753                 pids[idx]=$pid
11754         done
11755         wait
11756 }
11757 run_test 103b "umask lfs setstripe"
11758
11759 test_103c() {
11760         mkdir -p $DIR/$tdir
11761         cp -rp $DIR/$tdir $DIR/$tdir.bak
11762
11763         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11764                 error "$DIR/$tdir shouldn't contain default ACL"
11765         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11766                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11767         true
11768 }
11769 run_test 103c "'cp -rp' won't set empty acl"
11770
11771 test_103e() {
11772         local numacl
11773         local fileacl
11774         local saved_debug=$($LCTL get_param -n debug)
11775
11776         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11777                 skip "MDS needs to be at least 2.14.52"
11778
11779         large_xattr_enabled || skip_env "ea_inode feature disabled"
11780
11781         mkdir -p $DIR/$tdir
11782         # add big LOV EA to cause reply buffer overflow earlier
11783         $LFS setstripe -C 1000 $DIR/$tdir
11784         lctl set_param mdc.*-mdc*.stats=clear
11785
11786         $LCTL set_param debug=0
11787         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11788         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11789
11790         # add a large number of default ACLs (expect 8000+ for 2.13+)
11791         for U in {2..7000}; do
11792                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11793                         error "Able to add just $U default ACLs"
11794         done
11795         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11796         echo "$numacl default ACLs created"
11797
11798         stat $DIR/$tdir || error "Cannot stat directory"
11799         # check file creation
11800         touch $DIR/$tdir/$tfile ||
11801                 error "failed to create $tfile with $numacl default ACLs"
11802         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11803         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11804         echo "$fileacl ACLs were inherited"
11805         (( $fileacl == $numacl )) ||
11806                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11807         # check that new ACLs creation adds new ACLs to inherited ACLs
11808         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11809                 error "Cannot set new ACL"
11810         numacl=$((numacl + 1))
11811         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11812         (( $fileacl == $numacl )) ||
11813                 error "failed to add new ACL: $fileacl != $numacl as expected"
11814         # adds more ACLs to a file to reach their maximum at 8000+
11815         numacl=0
11816         for U in {20000..25000}; do
11817                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11818                 numacl=$((numacl + 1))
11819         done
11820         echo "Added $numacl more ACLs to the file"
11821         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11822         echo "Total $fileacl ACLs in file"
11823         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11824         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11825         rmdir $DIR/$tdir || error "Cannot remove directory"
11826 }
11827 run_test 103e "inheritance of big amount of default ACLs"
11828
11829 test_103f() {
11830         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11831                 skip "MDS needs to be at least 2.14.51"
11832
11833         large_xattr_enabled || skip_env "ea_inode feature disabled"
11834
11835         # enable changelog to consume more internal MDD buffers
11836         changelog_register
11837
11838         mkdir -p $DIR/$tdir
11839         # add big LOV EA
11840         $LFS setstripe -C 1000 $DIR/$tdir
11841         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11842         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11843         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11844         rmdir $DIR/$tdir || error "Cannot remove directory"
11845 }
11846 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11847
11848 test_104a() {
11849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11850
11851         touch $DIR/$tfile
11852         lfs df || error "lfs df failed"
11853         lfs df -ih || error "lfs df -ih failed"
11854         lfs df -h $DIR || error "lfs df -h $DIR failed"
11855         lfs df -i $DIR || error "lfs df -i $DIR failed"
11856         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11857         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11858
11859         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11860         lctl --device %$OSC deactivate
11861         lfs df || error "lfs df with deactivated OSC failed"
11862         lctl --device %$OSC activate
11863         # wait the osc back to normal
11864         wait_osc_import_ready client ost
11865
11866         lfs df || error "lfs df with reactivated OSC failed"
11867         rm -f $DIR/$tfile
11868 }
11869 run_test 104a "lfs df [-ih] [path] test ========================="
11870
11871 test_104b() {
11872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11873         [ $RUNAS_ID -eq $UID ] &&
11874                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11875
11876         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11877                         grep "Permission denied" | wc -l)))
11878         if [ $denied_cnt -ne 0 ]; then
11879                 error "lfs check servers test failed"
11880         fi
11881 }
11882 run_test 104b "$RUNAS lfs check servers test ===================="
11883
11884 #
11885 # Verify $1 is within range of $2.
11886 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11887 # $1 is <= 2% of $2. Else Fail.
11888 #
11889 value_in_range() {
11890         # Strip all units (M, G, T)
11891         actual=$(echo $1 | tr -d A-Z)
11892         expect=$(echo $2 | tr -d A-Z)
11893
11894         expect_lo=$(($expect * 98 / 100)) # 2% below
11895         expect_hi=$(($expect * 102 / 100)) # 2% above
11896
11897         # permit 2% drift above and below
11898         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11899 }
11900
11901 test_104c() {
11902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11903         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11904
11905         local ost_param="osd-zfs.$FSNAME-OST0000."
11906         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11907         local ofacets=$(get_facets OST)
11908         local mfacets=$(get_facets MDS)
11909         local saved_ost_blocks=
11910         local saved_mdt_blocks=
11911
11912         echo "Before recordsize change"
11913         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11914         df=($(df -h | grep "$MOUNT"$))
11915
11916         # For checking.
11917         echo "lfs output : ${lfs_df[*]}"
11918         echo "df  output : ${df[*]}"
11919
11920         for facet in ${ofacets//,/ }; do
11921                 if [ -z $saved_ost_blocks ]; then
11922                         saved_ost_blocks=$(do_facet $facet \
11923                                 lctl get_param -n $ost_param.blocksize)
11924                         echo "OST Blocksize: $saved_ost_blocks"
11925                 fi
11926                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11927                 do_facet $facet zfs set recordsize=32768 $ost
11928         done
11929
11930         # BS too small. Sufficient for functional testing.
11931         for facet in ${mfacets//,/ }; do
11932                 if [ -z $saved_mdt_blocks ]; then
11933                         saved_mdt_blocks=$(do_facet $facet \
11934                                 lctl get_param -n $mdt_param.blocksize)
11935                         echo "MDT Blocksize: $saved_mdt_blocks"
11936                 fi
11937                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11938                 do_facet $facet zfs set recordsize=32768 $mdt
11939         done
11940
11941         # Give new values chance to reflect change
11942         sleep 2
11943
11944         echo "After recordsize change"
11945         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11946         df_after=($(df -h | grep "$MOUNT"$))
11947
11948         # For checking.
11949         echo "lfs output : ${lfs_df_after[*]}"
11950         echo "df  output : ${df_after[*]}"
11951
11952         # Verify lfs df
11953         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11954                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11955         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11956                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11957         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11958                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11959
11960         # Verify df
11961         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11962                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11963         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11964                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11965         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11966                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11967
11968         # Restore MDT recordize back to original
11969         for facet in ${mfacets//,/ }; do
11970                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11971                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11972         done
11973
11974         # Restore OST recordize back to original
11975         for facet in ${ofacets//,/ }; do
11976                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11977                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11978         done
11979
11980         return 0
11981 }
11982 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11983
11984 test_104d() {
11985         (( $RUNAS_ID != $UID )) ||
11986                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11987
11988         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
11989                 skip "lustre version doesn't support lctl dl with non-root"
11990
11991         # debugfs only allows root users to access files, so the
11992         # previous move of the "devices" file to debugfs broke
11993         # "lctl dl" for non-root users. The LU-9680 Netlink
11994         # interface again allows non-root users to list devices.
11995         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
11996                 error "lctl dl doesn't work for non root"
11997
11998         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
11999         [ "$ost_count" -eq $OSTCOUNT ]  ||
12000                 error "lctl dl reports wrong number of OST devices"
12001
12002         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12003         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12004                 error "lctl dl reports wrong number of MDT devices"
12005 }
12006 run_test 104d "$RUNAS lctl dl test"
12007
12008 test_105a() {
12009         # doesn't work on 2.4 kernels
12010         touch $DIR/$tfile
12011         if $(flock_is_enabled); then
12012                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12013         else
12014                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12015         fi
12016         rm -f $DIR/$tfile
12017 }
12018 run_test 105a "flock when mounted without -o flock test ========"
12019
12020 test_105b() {
12021         touch $DIR/$tfile
12022         if $(flock_is_enabled); then
12023                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12024         else
12025                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12026         fi
12027         rm -f $DIR/$tfile
12028 }
12029 run_test 105b "fcntl when mounted without -o flock test ========"
12030
12031 test_105c() {
12032         touch $DIR/$tfile
12033         if $(flock_is_enabled); then
12034                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12035         else
12036                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12037         fi
12038         rm -f $DIR/$tfile
12039 }
12040 run_test 105c "lockf when mounted without -o flock test"
12041
12042 test_105d() { # bug 15924
12043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12044
12045         test_mkdir $DIR/$tdir
12046         flock_is_enabled || skip_env "mount w/o flock enabled"
12047         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12048         $LCTL set_param fail_loc=0x80000315
12049         flocks_test 2 $DIR/$tdir
12050 }
12051 run_test 105d "flock race (should not freeze) ========"
12052
12053 test_105e() { # bug 22660 && 22040
12054         flock_is_enabled || skip_env "mount w/o flock enabled"
12055
12056         touch $DIR/$tfile
12057         flocks_test 3 $DIR/$tfile
12058 }
12059 run_test 105e "Two conflicting flocks from same process"
12060
12061 test_106() { #bug 10921
12062         test_mkdir $DIR/$tdir
12063         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12064         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12065 }
12066 run_test 106 "attempt exec of dir followed by chown of that dir"
12067
12068 test_107() {
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070
12071         CDIR=`pwd`
12072         local file=core
12073
12074         cd $DIR
12075         rm -f $file
12076
12077         local save_pattern=$(sysctl -n kernel.core_pattern)
12078         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12079         sysctl -w kernel.core_pattern=$file
12080         sysctl -w kernel.core_uses_pid=0
12081
12082         ulimit -c unlimited
12083         sleep 60 &
12084         SLEEPPID=$!
12085
12086         sleep 1
12087
12088         kill -s 11 $SLEEPPID
12089         wait $SLEEPPID
12090         if [ -e $file ]; then
12091                 size=`stat -c%s $file`
12092                 [ $size -eq 0 ] && error "Fail to create core file $file"
12093         else
12094                 error "Fail to create core file $file"
12095         fi
12096         rm -f $file
12097         sysctl -w kernel.core_pattern=$save_pattern
12098         sysctl -w kernel.core_uses_pid=$save_uses_pid
12099         cd $CDIR
12100 }
12101 run_test 107 "Coredump on SIG"
12102
12103 test_110() {
12104         test_mkdir $DIR/$tdir
12105         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12106         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12107                 error "mkdir with 256 char should fail, but did not"
12108         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12109                 error "create with 255 char failed"
12110         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12111                 error "create with 256 char should fail, but did not"
12112
12113         ls -l $DIR/$tdir
12114         rm -rf $DIR/$tdir
12115 }
12116 run_test 110 "filename length checking"
12117
12118 #
12119 # Purpose: To verify dynamic thread (OSS) creation.
12120 #
12121 test_115() {
12122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12123         remote_ost_nodsh && skip "remote OST with nodsh"
12124
12125         # Lustre does not stop service threads once they are started.
12126         # Reset number of running threads to default.
12127         stopall
12128         setupall
12129
12130         local OSTIO_pre
12131         local save_params="$TMP/sanity-$TESTNAME.parameters"
12132
12133         # Get ll_ost_io count before I/O
12134         OSTIO_pre=$(do_facet ost1 \
12135                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12136         # Exit if lustre is not running (ll_ost_io not running).
12137         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12138
12139         echo "Starting with $OSTIO_pre threads"
12140         local thread_max=$((OSTIO_pre * 2))
12141         local rpc_in_flight=$((thread_max * 2))
12142         # this is limited to OSC_MAX_RIF_MAX (256)
12143         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12144         thread_max=$((rpc_in_flight / 2))
12145         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12146                 return
12147
12148         # Number of I/O Process proposed to be started.
12149         local nfiles
12150         local facets=$(get_facets OST)
12151
12152         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12153         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12154
12155         # Set in_flight to $rpc_in_flight
12156         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12157                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12158         nfiles=${rpc_in_flight}
12159         # Set ost thread_max to $thread_max
12160         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12161
12162         # 5 Minutes should be sufficient for max number of OSS
12163         # threads(thread_max) to be created.
12164         local timeout=300
12165
12166         # Start I/O.
12167         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12168         test_mkdir $DIR/$tdir
12169         for i in $(seq $nfiles); do
12170                 local file=$DIR/$tdir/${tfile}-$i
12171                 $LFS setstripe -c -1 -i 0 $file
12172                 ($WTL $file $timeout)&
12173         done
12174
12175         # I/O Started - Wait for thread_started to reach thread_max or report
12176         # error if thread_started is more than thread_max.
12177         echo "Waiting for thread_started to reach thread_max"
12178         local thread_started=0
12179         local end_time=$((SECONDS + timeout))
12180
12181         while [ $SECONDS -le $end_time ] ; do
12182                 echo -n "."
12183                 # Get ost i/o thread_started count.
12184                 thread_started=$(do_facet ost1 \
12185                         "$LCTL get_param \
12186                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12187                 # Break out if thread_started is equal/greater than thread_max
12188                 if [[ $thread_started -ge $thread_max ]]; then
12189                         echo ll_ost_io thread_started $thread_started, \
12190                                 equal/greater than thread_max $thread_max
12191                         break
12192                 fi
12193                 sleep 1
12194         done
12195
12196         # Cleanup - We have the numbers, Kill i/o jobs if running.
12197         jobcount=($(jobs -p))
12198         for i in $(seq 0 $((${#jobcount[@]}-1)))
12199         do
12200                 kill -9 ${jobcount[$i]}
12201                 if [ $? -ne 0 ] ; then
12202                         echo Warning: \
12203                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12204                 fi
12205         done
12206
12207         # Cleanup files left by WTL binary.
12208         for i in $(seq $nfiles); do
12209                 local file=$DIR/$tdir/${tfile}-$i
12210                 rm -rf $file
12211                 if [ $? -ne 0 ] ; then
12212                         echo "Warning: Failed to delete file $file"
12213                 fi
12214         done
12215
12216         restore_lustre_params <$save_params
12217         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12218
12219         # Error out if no new thread has started or Thread started is greater
12220         # than thread max.
12221         if [[ $thread_started -le $OSTIO_pre ||
12222                         $thread_started -gt $thread_max ]]; then
12223                 error "ll_ost_io: thread_started $thread_started" \
12224                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12225                       "No new thread started or thread started greater " \
12226                       "than thread_max."
12227         fi
12228 }
12229 run_test 115 "verify dynamic thread creation===================="
12230
12231 test_116a() { # was previously test_116()
12232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12233         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12234         remote_mds_nodsh && skip "remote MDS with nodsh"
12235
12236         echo -n "Free space priority "
12237         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12238                 head -n1
12239         declare -a AVAIL
12240         free_min_max
12241
12242         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12243         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12244         stack_trap simple_cleanup_common
12245
12246         # Check if we need to generate uneven OSTs
12247         test_mkdir -p $DIR/$tdir/OST${MINI}
12248         local FILL=$((MINV / 4))
12249         local DIFF=$((MAXV - MINV))
12250         local DIFF2=$((DIFF * 100 / MINV))
12251
12252         local threshold=$(do_facet $SINGLEMDS \
12253                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12254         threshold=${threshold%%%}
12255         echo -n "Check for uneven OSTs: "
12256         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12257
12258         if [[ $DIFF2 -gt $threshold ]]; then
12259                 echo "ok"
12260                 echo "Don't need to fill OST$MINI"
12261         else
12262                 # generate uneven OSTs. Write 2% over the QOS threshold value
12263                 echo "no"
12264                 DIFF=$((threshold - DIFF2 + 2))
12265                 DIFF2=$((MINV * DIFF / 100))
12266                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12267                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12268                         error "setstripe failed"
12269                 DIFF=$((DIFF2 / 2048))
12270                 i=0
12271                 while [ $i -lt $DIFF ]; do
12272                         i=$((i + 1))
12273                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12274                                 bs=2M count=1 2>/dev/null
12275                         echo -n .
12276                 done
12277                 echo .
12278                 sync
12279                 sleep_maxage
12280                 free_min_max
12281         fi
12282
12283         DIFF=$((MAXV - MINV))
12284         DIFF2=$((DIFF * 100 / MINV))
12285         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12286         if [ $DIFF2 -gt $threshold ]; then
12287                 echo "ok"
12288         else
12289                 skip "QOS imbalance criteria not met"
12290         fi
12291
12292         MINI1=$MINI
12293         MINV1=$MINV
12294         MAXI1=$MAXI
12295         MAXV1=$MAXV
12296
12297         # now fill using QOS
12298         $LFS setstripe -c 1 $DIR/$tdir
12299         FILL=$((FILL / 200))
12300         if [ $FILL -gt 600 ]; then
12301                 FILL=600
12302         fi
12303         echo "writing $FILL files to QOS-assigned OSTs"
12304         i=0
12305         while [ $i -lt $FILL ]; do
12306                 i=$((i + 1))
12307                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12308                         count=1 2>/dev/null
12309                 echo -n .
12310         done
12311         echo "wrote $i 200k files"
12312         sync
12313         sleep_maxage
12314
12315         echo "Note: free space may not be updated, so measurements might be off"
12316         free_min_max
12317         DIFF2=$((MAXV - MINV))
12318         echo "free space delta: orig $DIFF final $DIFF2"
12319         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12320         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12321         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12322         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12323         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12324         if [[ $DIFF -gt 0 ]]; then
12325                 FILL=$((DIFF2 * 100 / DIFF - 100))
12326                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12327         fi
12328
12329         # Figure out which files were written where
12330         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12331                awk '/'$MINI1': / {print $2; exit}')
12332         echo $UUID
12333         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12334         echo "$MINC files created on smaller OST $MINI1"
12335         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12336                awk '/'$MAXI1': / {print $2; exit}')
12337         echo $UUID
12338         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12339         echo "$MAXC files created on larger OST $MAXI1"
12340         if [[ $MINC -gt 0 ]]; then
12341                 FILL=$((MAXC * 100 / MINC - 100))
12342                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12343         fi
12344         [[ $MAXC -gt $MINC ]] ||
12345                 error_ignore LU-9 "stripe QOS didn't balance free space"
12346 }
12347 run_test 116a "stripe QOS: free space balance ==================="
12348
12349 test_116b() { # LU-2093
12350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12351         remote_mds_nodsh && skip "remote MDS with nodsh"
12352
12353 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12354         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12355                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12356         [ -z "$old_rr" ] && skip "no QOS"
12357         do_facet $SINGLEMDS lctl set_param \
12358                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12359         mkdir -p $DIR/$tdir
12360         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12361         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12362         do_facet $SINGLEMDS lctl set_param fail_loc=0
12363         rm -rf $DIR/$tdir
12364         do_facet $SINGLEMDS lctl set_param \
12365                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12366 }
12367 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12368
12369 test_117() # bug 10891
12370 {
12371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12372
12373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12374         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12375         lctl set_param fail_loc=0x21e
12376         > $DIR/$tfile || error "truncate failed"
12377         lctl set_param fail_loc=0
12378         echo "Truncate succeeded."
12379         rm -f $DIR/$tfile
12380 }
12381 run_test 117 "verify osd extend =========="
12382
12383 NO_SLOW_RESENDCOUNT=4
12384 export OLD_RESENDCOUNT=""
12385 set_resend_count () {
12386         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12387         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12388         lctl set_param -n $PROC_RESENDCOUNT $1
12389         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12390 }
12391
12392 # for reduce test_118* time (b=14842)
12393 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12394
12395 # Reset async IO behavior after error case
12396 reset_async() {
12397         FILE=$DIR/reset_async
12398
12399         # Ensure all OSCs are cleared
12400         $LFS setstripe -c -1 $FILE
12401         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12402         sync
12403         rm $FILE
12404 }
12405
12406 test_118a() #bug 11710
12407 {
12408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12409
12410         reset_async
12411
12412         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12415
12416         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12417                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12418                 return 1;
12419         fi
12420         rm -f $DIR/$tfile
12421 }
12422 run_test 118a "verify O_SYNC works =========="
12423
12424 test_118b()
12425 {
12426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12427         remote_ost_nodsh && skip "remote OST with nodsh"
12428
12429         reset_async
12430
12431         #define OBD_FAIL_SRV_ENOENT 0x217
12432         set_nodes_failloc "$(osts_nodes)" 0x217
12433         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12434         RC=$?
12435         set_nodes_failloc "$(osts_nodes)" 0
12436         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12437         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12438                     grep -c writeback)
12439
12440         if [[ $RC -eq 0 ]]; then
12441                 error "Must return error due to dropped pages, rc=$RC"
12442                 return 1;
12443         fi
12444
12445         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12446                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12447                 return 1;
12448         fi
12449
12450         echo "Dirty pages not leaked on ENOENT"
12451
12452         # Due to the above error the OSC will issue all RPCs syncronously
12453         # until a subsequent RPC completes successfully without error.
12454         $MULTIOP $DIR/$tfile Ow4096yc
12455         rm -f $DIR/$tfile
12456
12457         return 0
12458 }
12459 run_test 118b "Reclaim dirty pages on fatal error =========="
12460
12461 test_118c()
12462 {
12463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12464
12465         # for 118c, restore the original resend count, LU-1940
12466         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12467                                 set_resend_count $OLD_RESENDCOUNT
12468         remote_ost_nodsh && skip "remote OST with nodsh"
12469
12470         reset_async
12471
12472         #define OBD_FAIL_OST_EROFS               0x216
12473         set_nodes_failloc "$(osts_nodes)" 0x216
12474
12475         # multiop should block due to fsync until pages are written
12476         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12477         MULTIPID=$!
12478         sleep 1
12479
12480         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12481                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12482         fi
12483
12484         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12485                     grep -c writeback)
12486         if [[ $WRITEBACK -eq 0 ]]; then
12487                 error "No page in writeback, writeback=$WRITEBACK"
12488         fi
12489
12490         set_nodes_failloc "$(osts_nodes)" 0
12491         wait $MULTIPID
12492         RC=$?
12493         if [[ $RC -ne 0 ]]; then
12494                 error "Multiop fsync failed, rc=$RC"
12495         fi
12496
12497         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12498         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12499                     grep -c writeback)
12500         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12501                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12502         fi
12503
12504         rm -f $DIR/$tfile
12505         echo "Dirty pages flushed via fsync on EROFS"
12506         return 0
12507 }
12508 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12509
12510 # continue to use small resend count to reduce test_118* time (b=14842)
12511 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12512
12513 test_118d()
12514 {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516         remote_ost_nodsh && skip "remote OST with nodsh"
12517
12518         reset_async
12519
12520         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12521         set_nodes_failloc "$(osts_nodes)" 0x214
12522         # multiop should block due to fsync until pages are written
12523         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12524         MULTIPID=$!
12525         sleep 1
12526
12527         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12528                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12529         fi
12530
12531         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12532                     grep -c writeback)
12533         if [[ $WRITEBACK -eq 0 ]]; then
12534                 error "No page in writeback, writeback=$WRITEBACK"
12535         fi
12536
12537         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12538         set_nodes_failloc "$(osts_nodes)" 0
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 gaurenteed flushed via fsync"
12549         return 0
12550 }
12551 run_test 118d "Fsync validation inject a delay of the bulk =========="
12552
12553 test_118f() {
12554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12555
12556         reset_async
12557
12558         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12559         lctl set_param fail_loc=0x8000040a
12560
12561         # Should simulate EINVAL error which is fatal
12562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12563         RC=$?
12564         if [[ $RC -eq 0 ]]; then
12565                 error "Must return error due to dropped pages, rc=$RC"
12566         fi
12567
12568         lctl set_param fail_loc=0x0
12569
12570         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12571         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12572         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12573                     grep -c writeback)
12574         if [[ $LOCKED -ne 0 ]]; then
12575                 error "Locked pages remain in cache, locked=$LOCKED"
12576         fi
12577
12578         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12579                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12580         fi
12581
12582         rm -f $DIR/$tfile
12583         echo "No pages locked after fsync"
12584
12585         reset_async
12586         return 0
12587 }
12588 run_test 118f "Simulate unrecoverable OSC side error =========="
12589
12590 test_118g() {
12591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12592
12593         reset_async
12594
12595         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12596         lctl set_param fail_loc=0x406
12597
12598         # simulate local -ENOMEM
12599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12600         RC=$?
12601
12602         lctl set_param fail_loc=0
12603         if [[ $RC -eq 0 ]]; then
12604                 error "Must return error due to dropped pages, rc=$RC"
12605         fi
12606
12607         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12608         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12609         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12610                         grep -c writeback)
12611         if [[ $LOCKED -ne 0 ]]; then
12612                 error "Locked pages remain in cache, locked=$LOCKED"
12613         fi
12614
12615         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12616                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12617         fi
12618
12619         rm -f $DIR/$tfile
12620         echo "No pages locked after fsync"
12621
12622         reset_async
12623         return 0
12624 }
12625 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12626
12627 test_118h() {
12628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12629         remote_ost_nodsh && skip "remote OST with nodsh"
12630
12631         reset_async
12632
12633         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12634         set_nodes_failloc "$(osts_nodes)" 0x20e
12635         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12636         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12637         RC=$?
12638
12639         set_nodes_failloc "$(osts_nodes)" 0
12640         if [[ $RC -eq 0 ]]; then
12641                 error "Must return error due to dropped pages, rc=$RC"
12642         fi
12643
12644         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12645         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12646         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12647                     grep -c writeback)
12648         if [[ $LOCKED -ne 0 ]]; then
12649                 error "Locked pages remain in cache, locked=$LOCKED"
12650         fi
12651
12652         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12653                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12654         fi
12655
12656         rm -f $DIR/$tfile
12657         echo "No pages locked after fsync"
12658
12659         return 0
12660 }
12661 run_test 118h "Verify timeout in handling recoverables errors  =========="
12662
12663 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12664
12665 test_118i() {
12666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12667         remote_ost_nodsh && skip "remote OST with nodsh"
12668
12669         reset_async
12670
12671         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12672         set_nodes_failloc "$(osts_nodes)" 0x20e
12673
12674         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12676         PID=$!
12677         sleep 5
12678         set_nodes_failloc "$(osts_nodes)" 0
12679
12680         wait $PID
12681         RC=$?
12682         if [[ $RC -ne 0 ]]; then
12683                 error "got error, but should be not, rc=$RC"
12684         fi
12685
12686         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12687         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12688         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12689         if [[ $LOCKED -ne 0 ]]; then
12690                 error "Locked pages remain in cache, locked=$LOCKED"
12691         fi
12692
12693         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12694                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12695         fi
12696
12697         rm -f $DIR/$tfile
12698         echo "No pages locked after fsync"
12699
12700         return 0
12701 }
12702 run_test 118i "Fix error before timeout in recoverable error  =========="
12703
12704 [ "$SLOW" = "no" ] && set_resend_count 4
12705
12706 test_118j() {
12707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12708         remote_ost_nodsh && skip "remote OST with nodsh"
12709
12710         reset_async
12711
12712         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12713         set_nodes_failloc "$(osts_nodes)" 0x220
12714
12715         # return -EIO from OST
12716         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12717         RC=$?
12718         set_nodes_failloc "$(osts_nodes)" 0x0
12719         if [[ $RC -eq 0 ]]; then
12720                 error "Must return error due to dropped pages, rc=$RC"
12721         fi
12722
12723         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12724         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12725         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12726         if [[ $LOCKED -ne 0 ]]; then
12727                 error "Locked pages remain in cache, locked=$LOCKED"
12728         fi
12729
12730         # in recoverable error on OST we want resend and stay until it finished
12731         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12732                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12733         fi
12734
12735         rm -f $DIR/$tfile
12736         echo "No pages locked after fsync"
12737
12738         return 0
12739 }
12740 run_test 118j "Simulate unrecoverable OST side error =========="
12741
12742 test_118k()
12743 {
12744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12745         remote_ost_nodsh && skip "remote OSTs with nodsh"
12746
12747         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12748         set_nodes_failloc "$(osts_nodes)" 0x20e
12749         test_mkdir $DIR/$tdir
12750
12751         for ((i=0;i<10;i++)); do
12752                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12753                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12754                 SLEEPPID=$!
12755                 sleep 0.500s
12756                 kill $SLEEPPID
12757                 wait $SLEEPPID
12758         done
12759
12760         set_nodes_failloc "$(osts_nodes)" 0
12761         rm -rf $DIR/$tdir
12762 }
12763 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12764
12765 test_118l() # LU-646
12766 {
12767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12768
12769         test_mkdir $DIR/$tdir
12770         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12771         rm -rf $DIR/$tdir
12772 }
12773 run_test 118l "fsync dir"
12774
12775 test_118m() # LU-3066
12776 {
12777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12778
12779         test_mkdir $DIR/$tdir
12780         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12781         rm -rf $DIR/$tdir
12782 }
12783 run_test 118m "fdatasync dir ========="
12784
12785 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12786
12787 test_118n()
12788 {
12789         local begin
12790         local end
12791
12792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12793         remote_ost_nodsh && skip "remote OSTs with nodsh"
12794
12795         # Sleep to avoid a cached response.
12796         #define OBD_STATFS_CACHE_SECONDS 1
12797         sleep 2
12798
12799         # Inject a 10 second delay in the OST_STATFS handler.
12800         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12801         set_nodes_failloc "$(osts_nodes)" 0x242
12802
12803         begin=$SECONDS
12804         stat --file-system $MOUNT > /dev/null
12805         end=$SECONDS
12806
12807         set_nodes_failloc "$(osts_nodes)" 0
12808
12809         if ((end - begin > 20)); then
12810             error "statfs took $((end - begin)) seconds, expected 10"
12811         fi
12812 }
12813 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12814
12815 test_119a() # bug 11737
12816 {
12817         BSIZE=$((512 * 1024))
12818         directio write $DIR/$tfile 0 1 $BSIZE
12819         # We ask to read two blocks, which is more than a file size.
12820         # directio will indicate an error when requested and actual
12821         # sizes aren't equeal (a normal situation in this case) and
12822         # print actual read amount.
12823         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12824         if [ "$NOB" != "$BSIZE" ]; then
12825                 error "read $NOB bytes instead of $BSIZE"
12826         fi
12827         rm -f $DIR/$tfile
12828 }
12829 run_test 119a "Short directIO read must return actual read amount"
12830
12831 test_119b() # bug 11737
12832 {
12833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12834
12835         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12836         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12837         sync
12838         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12839                 error "direct read failed"
12840         rm -f $DIR/$tfile
12841 }
12842 run_test 119b "Sparse directIO read must return actual read amount"
12843
12844 test_119c() # bug 13099
12845 {
12846         BSIZE=1048576
12847         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12848         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12849         rm -f $DIR/$tfile
12850 }
12851 run_test 119c "Testing for direct read hitting hole"
12852
12853 test_119d() # bug 15950
12854 {
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856
12857         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12858         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12859         BSIZE=1048576
12860         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12861         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12862         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12863         lctl set_param fail_loc=0x40d
12864         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12865         pid_dio=$!
12866         sleep 1
12867         cat $DIR/$tfile > /dev/null &
12868         lctl set_param fail_loc=0
12869         pid_reads=$!
12870         wait $pid_dio
12871         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12872         sleep 2
12873         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12874         error "the read rpcs have not completed in 2s"
12875         rm -f $DIR/$tfile
12876         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12877 }
12878 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12879
12880 test_120a() {
12881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883         test_mkdir -i0 -c1 $DIR/$tdir
12884         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12885                 skip_env "no early lock cancel on server"
12886
12887         lru_resize_disable mdc
12888         lru_resize_disable osc
12889         cancel_lru_locks mdc
12890         # asynchronous object destroy at MDT could cause bl ast to client
12891         cancel_lru_locks osc
12892
12893         stat $DIR/$tdir > /dev/null
12894         can1=$(do_facet mds1 \
12895                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12896                awk '/ldlm_cancel/ {print $2}')
12897         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12898                awk '/ldlm_bl_callback/ {print $2}')
12899         test_mkdir -i0 -c1 $DIR/$tdir/d1
12900         can2=$(do_facet mds1 \
12901                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12902                awk '/ldlm_cancel/ {print $2}')
12903         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12904                awk '/ldlm_bl_callback/ {print $2}')
12905         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12906         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12907         lru_resize_enable mdc
12908         lru_resize_enable osc
12909 }
12910 run_test 120a "Early Lock Cancel: mkdir test"
12911
12912 test_120b() {
12913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12914         remote_mds_nodsh && skip "remote MDS with nodsh"
12915         test_mkdir $DIR/$tdir
12916         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12917                 skip_env "no early lock cancel on server"
12918
12919         lru_resize_disable mdc
12920         lru_resize_disable osc
12921         cancel_lru_locks mdc
12922         stat $DIR/$tdir > /dev/null
12923         can1=$(do_facet $SINGLEMDS \
12924                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12925                awk '/ldlm_cancel/ {print $2}')
12926         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12927                awk '/ldlm_bl_callback/ {print $2}')
12928         touch $DIR/$tdir/f1
12929         can2=$(do_facet $SINGLEMDS \
12930                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12931                awk '/ldlm_cancel/ {print $2}')
12932         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12933                awk '/ldlm_bl_callback/ {print $2}')
12934         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12935         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12936         lru_resize_enable mdc
12937         lru_resize_enable osc
12938 }
12939 run_test 120b "Early Lock Cancel: create test"
12940
12941 test_120c() {
12942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12943         remote_mds_nodsh && skip "remote MDS with nodsh"
12944         test_mkdir -i0 -c1 $DIR/$tdir
12945         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12946                 skip "no early lock cancel on server"
12947
12948         lru_resize_disable mdc
12949         lru_resize_disable osc
12950         test_mkdir -i0 -c1 $DIR/$tdir/d1
12951         test_mkdir -i0 -c1 $DIR/$tdir/d2
12952         touch $DIR/$tdir/d1/f1
12953         cancel_lru_locks mdc
12954         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12955         can1=$(do_facet mds1 \
12956                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12957                awk '/ldlm_cancel/ {print $2}')
12958         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12959                awk '/ldlm_bl_callback/ {print $2}')
12960         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12961         can2=$(do_facet mds1 \
12962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12963                awk '/ldlm_cancel/ {print $2}')
12964         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12965                awk '/ldlm_bl_callback/ {print $2}')
12966         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12967         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12968         lru_resize_enable mdc
12969         lru_resize_enable osc
12970 }
12971 run_test 120c "Early Lock Cancel: link test"
12972
12973 test_120d() {
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975         remote_mds_nodsh && skip "remote MDS with nodsh"
12976         test_mkdir -i0 -c1 $DIR/$tdir
12977         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12978                 skip_env "no early lock cancel on server"
12979
12980         lru_resize_disable mdc
12981         lru_resize_disable osc
12982         touch $DIR/$tdir
12983         cancel_lru_locks mdc
12984         stat $DIR/$tdir > /dev/null
12985         can1=$(do_facet mds1 \
12986                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12987                awk '/ldlm_cancel/ {print $2}')
12988         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12989                awk '/ldlm_bl_callback/ {print $2}')
12990         chmod a+x $DIR/$tdir
12991         can2=$(do_facet mds1 \
12992                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12993                awk '/ldlm_cancel/ {print $2}')
12994         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12995                awk '/ldlm_bl_callback/ {print $2}')
12996         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12997         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12998         lru_resize_enable mdc
12999         lru_resize_enable osc
13000 }
13001 run_test 120d "Early Lock Cancel: setattr test"
13002
13003 test_120e() {
13004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13005         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13006                 skip_env "no early lock cancel on server"
13007         remote_mds_nodsh && skip "remote MDS with nodsh"
13008
13009         local dlmtrace_set=false
13010
13011         test_mkdir -i0 -c1 $DIR/$tdir
13012         lru_resize_disable mdc
13013         lru_resize_disable osc
13014         ! $LCTL get_param debug | grep -q dlmtrace &&
13015                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13016         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13017         cancel_lru_locks mdc
13018         cancel_lru_locks osc
13019         dd if=$DIR/$tdir/f1 of=/dev/null
13020         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13021         # XXX client can not do early lock cancel of OST lock
13022         # during unlink (LU-4206), so cancel osc lock now.
13023         sleep 2
13024         cancel_lru_locks osc
13025         can1=$(do_facet mds1 \
13026                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13027                awk '/ldlm_cancel/ {print $2}')
13028         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13029                awk '/ldlm_bl_callback/ {print $2}')
13030         unlink $DIR/$tdir/f1
13031         sleep 5
13032         can2=$(do_facet mds1 \
13033                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13034                awk '/ldlm_cancel/ {print $2}')
13035         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13036                awk '/ldlm_bl_callback/ {print $2}')
13037         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13038                 $LCTL dk $TMP/cancel.debug.txt
13039         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13040                 $LCTL dk $TMP/blocking.debug.txt
13041         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13042         lru_resize_enable mdc
13043         lru_resize_enable osc
13044 }
13045 run_test 120e "Early Lock Cancel: unlink test"
13046
13047 test_120f() {
13048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13049         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13050                 skip_env "no early lock cancel on server"
13051         remote_mds_nodsh && skip "remote MDS with nodsh"
13052
13053         test_mkdir -i0 -c1 $DIR/$tdir
13054         lru_resize_disable mdc
13055         lru_resize_disable osc
13056         test_mkdir -i0 -c1 $DIR/$tdir/d1
13057         test_mkdir -i0 -c1 $DIR/$tdir/d2
13058         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13059         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13060         cancel_lru_locks mdc
13061         cancel_lru_locks osc
13062         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13063         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13064         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13065         # XXX client can not do early lock cancel of OST lock
13066         # during rename (LU-4206), so cancel osc lock now.
13067         sleep 2
13068         cancel_lru_locks osc
13069         can1=$(do_facet mds1 \
13070                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13071                awk '/ldlm_cancel/ {print $2}')
13072         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13073                awk '/ldlm_bl_callback/ {print $2}')
13074         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13075         sleep 5
13076         can2=$(do_facet mds1 \
13077                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13078                awk '/ldlm_cancel/ {print $2}')
13079         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13080                awk '/ldlm_bl_callback/ {print $2}')
13081         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13082         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13083         lru_resize_enable mdc
13084         lru_resize_enable osc
13085 }
13086 run_test 120f "Early Lock Cancel: rename test"
13087
13088 test_120g() {
13089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13090         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13091                 skip_env "no early lock cancel on server"
13092         remote_mds_nodsh && skip "remote MDS with nodsh"
13093
13094         lru_resize_disable mdc
13095         lru_resize_disable osc
13096         count=10000
13097         echo create $count files
13098         test_mkdir $DIR/$tdir
13099         cancel_lru_locks mdc
13100         cancel_lru_locks osc
13101         t0=$(date +%s)
13102
13103         can0=$(do_facet $SINGLEMDS \
13104                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13105                awk '/ldlm_cancel/ {print $2}')
13106         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13107                awk '/ldlm_bl_callback/ {print $2}')
13108         createmany -o $DIR/$tdir/f $count
13109         sync
13110         can1=$(do_facet $SINGLEMDS \
13111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13112                awk '/ldlm_cancel/ {print $2}')
13113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13114                awk '/ldlm_bl_callback/ {print $2}')
13115         t1=$(date +%s)
13116         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13117         echo rm $count files
13118         rm -r $DIR/$tdir
13119         sync
13120         can2=$(do_facet $SINGLEMDS \
13121                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13122                awk '/ldlm_cancel/ {print $2}')
13123         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13124                awk '/ldlm_bl_callback/ {print $2}')
13125         t2=$(date +%s)
13126         echo total: $count removes in $((t2-t1))
13127         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13128         sleep 2
13129         # wait for commitment of removal
13130         lru_resize_enable mdc
13131         lru_resize_enable osc
13132 }
13133 run_test 120g "Early Lock Cancel: performance test"
13134
13135 test_121() { #bug #10589
13136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13137
13138         rm -rf $DIR/$tfile
13139         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13140 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13141         lctl set_param fail_loc=0x310
13142         cancel_lru_locks osc > /dev/null
13143         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13144         lctl set_param fail_loc=0
13145         [[ $reads -eq $writes ]] ||
13146                 error "read $reads blocks, must be $writes blocks"
13147 }
13148 run_test 121 "read cancel race ========="
13149
13150 test_123a_base() { # was test 123, statahead(bug 11401)
13151         local lsx="$1"
13152
13153         SLOWOK=0
13154         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13155                 log "testing UP system. Performance may be lower than expected."
13156                 SLOWOK=1
13157         fi
13158         running_in_vm && SLOWOK=1
13159
13160         rm -rf $DIR/$tdir
13161         test_mkdir $DIR/$tdir
13162         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13163         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13164         MULT=10
13165         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13166                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13167
13168                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13169                 lctl set_param -n llite.*.statahead_max 0
13170                 lctl get_param llite.*.statahead_max
13171                 cancel_lru_locks mdc
13172                 cancel_lru_locks osc
13173                 stime=$(date +%s)
13174                 time $lsx $DIR/$tdir | wc -l
13175                 etime=$(date +%s)
13176                 delta=$((etime - stime))
13177                 log "$lsx $i files without statahead: $delta sec"
13178                 lctl set_param llite.*.statahead_max=$max
13179
13180                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13181                          awk '/statahead.wrong:/ { print $NF }')
13182                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13183                 cancel_lru_locks mdc
13184                 cancel_lru_locks osc
13185                 stime=$(date +%s)
13186                 time $lsx $DIR/$tdir | wc -l
13187                 etime=$(date +%s)
13188                 delta_sa=$((etime - stime))
13189                 log "$lsx $i files with statahead: $delta_sa sec"
13190                 lctl get_param -n llite.*.statahead_stats
13191                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13192                          awk '/statahead.wrong:/ { print $NF }')
13193
13194                 [[ $swrong -lt $ewrong ]] &&
13195                         log "statahead was stopped, maybe too many locks held!"
13196                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13197
13198                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13199                         max=$(lctl get_param -n llite.*.statahead_max |
13200                                 head -n 1)
13201                         lctl set_param -n llite.*.statahead_max 0
13202                         lctl get_param llite.*.statahead_max
13203                         cancel_lru_locks mdc
13204                         cancel_lru_locks osc
13205                         stime=$(date +%s)
13206                         time $lsx $DIR/$tdir | wc -l
13207                         etime=$(date +%s)
13208                         delta=$((etime - stime))
13209                         log "$lsx $i files again without statahead: $delta sec"
13210                         lctl set_param llite.*.statahead_max=$max
13211                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13212                                 if [ $SLOWOK -eq 0 ]; then
13213                                         error "$lsx $i files is slower with statahead!"
13214                                 else
13215                                         log "$lsx $i files is slower with statahead!"
13216                                 fi
13217                                 break
13218                         fi
13219                 fi
13220
13221                 [ $delta -gt 20 ] && break
13222                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13223                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13224         done
13225         log "$lsx done"
13226
13227         stime=$(date +%s)
13228         rm -r $DIR/$tdir
13229         sync
13230         etime=$(date +%s)
13231         delta=$((etime - stime))
13232         log "rm -r $DIR/$tdir/: $delta seconds"
13233         log "rm done"
13234         lctl get_param -n llite.*.statahead_stats
13235 }
13236
13237 test_123aa() {
13238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13239
13240         test_123a_base "ls -l"
13241 }
13242 run_test 123aa "verify statahead work"
13243
13244 test_123ab() {
13245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13246
13247         statx_supported || skip_env "Test must be statx() syscall supported"
13248
13249         test_123a_base "$STATX -l"
13250 }
13251 run_test 123ab "verify statahead work by using statx"
13252
13253 test_123ac() {
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255
13256         statx_supported || skip_env "Test must be statx() syscall supported"
13257
13258         local rpcs_before
13259         local rpcs_after
13260         local agl_before
13261         local agl_after
13262
13263         cancel_lru_locks $OSC
13264         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13265         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13266                      awk '/agl.total:/ { print $NF }')
13267         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13268         test_123a_base "$STATX --cached=always -D"
13269         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13270                     awk '/agl.total:/ { print $NF }')
13271         [ $agl_before -eq $agl_after ] ||
13272                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13273         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13274         [ $rpcs_after -eq $rpcs_before ] ||
13275                 error "$STATX should not send glimpse RPCs to $OSC"
13276 }
13277 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13278
13279 test_123b () { # statahead(bug 15027)
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281
13282         test_mkdir $DIR/$tdir
13283         createmany -o $DIR/$tdir/$tfile-%d 1000
13284
13285         cancel_lru_locks mdc
13286         cancel_lru_locks osc
13287
13288 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13289         lctl set_param fail_loc=0x80000803
13290         ls -lR $DIR/$tdir > /dev/null
13291         log "ls done"
13292         lctl set_param fail_loc=0x0
13293         lctl get_param -n llite.*.statahead_stats
13294         rm -r $DIR/$tdir
13295         sync
13296
13297 }
13298 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13299
13300 test_123c() {
13301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13302
13303         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13304         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13305         touch $DIR/$tdir.1/{1..3}
13306         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13307
13308         remount_client $MOUNT
13309
13310         $MULTIOP $DIR/$tdir.0 Q
13311
13312         # let statahead to complete
13313         ls -l $DIR/$tdir.0 > /dev/null
13314
13315         testid=$(echo $TESTNAME | tr '_' ' ')
13316         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13317                 error "statahead warning" || true
13318 }
13319 run_test 123c "Can not initialize inode warning on DNE statahead"
13320
13321 test_123d() {
13322         local num=100
13323         local swrong
13324         local ewrong
13325
13326         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13327         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13328                 error "setdirstripe $DIR/$tdir failed"
13329         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13330         remount_client $MOUNT
13331         $LCTL get_param llite.*.statahead_max
13332         $LCTL set_param llite.*.statahead_stats=0 ||
13333                 error "clear statahead_stats failed"
13334         swrong=$(lctl get_param -n llite.*.statahead_stats |
13335                  awk '/statahead.wrong:/ { print $NF }')
13336         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13337         # wait for statahead thread finished to update hit/miss stats.
13338         sleep 1
13339         $LCTL get_param -n llite.*.statahead_stats
13340         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13341                  awk '/statahead.wrong:/ { print $NF }')
13342         (( $swrong == $ewrong )) ||
13343                 log "statahead was stopped, maybe too many locks held!"
13344 }
13345 run_test 123d "Statahead on striped directories works correctly"
13346
13347 test_124a() {
13348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13349         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13350                 skip_env "no lru resize on server"
13351
13352         local NR=2000
13353
13354         test_mkdir $DIR/$tdir
13355
13356         log "create $NR files at $DIR/$tdir"
13357         createmany -o $DIR/$tdir/f $NR ||
13358                 error "failed to create $NR files in $DIR/$tdir"
13359
13360         cancel_lru_locks mdc
13361         ls -l $DIR/$tdir > /dev/null
13362
13363         local NSDIR=""
13364         local LRU_SIZE=0
13365         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13366                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13367                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13368                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13369                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13370                         log "NSDIR=$NSDIR"
13371                         log "NS=$(basename $NSDIR)"
13372                         break
13373                 fi
13374         done
13375
13376         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13377                 skip "Not enough cached locks created!"
13378         fi
13379         log "LRU=$LRU_SIZE"
13380
13381         local SLEEP=30
13382
13383         # We know that lru resize allows one client to hold $LIMIT locks
13384         # for 10h. After that locks begin to be killed by client.
13385         local MAX_HRS=10
13386         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13387         log "LIMIT=$LIMIT"
13388         if [ $LIMIT -lt $LRU_SIZE ]; then
13389                 skip "Limit is too small $LIMIT"
13390         fi
13391
13392         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13393         # killing locks. Some time was spent for creating locks. This means
13394         # that up to the moment of sleep finish we must have killed some of
13395         # them (10-100 locks). This depends on how fast ther were created.
13396         # Many of them were touched in almost the same moment and thus will
13397         # be killed in groups.
13398         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13399
13400         # Use $LRU_SIZE_B here to take into account real number of locks
13401         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13402         local LRU_SIZE_B=$LRU_SIZE
13403         log "LVF=$LVF"
13404         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13405         log "OLD_LVF=$OLD_LVF"
13406         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13407
13408         # Let's make sure that we really have some margin. Client checks
13409         # cached locks every 10 sec.
13410         SLEEP=$((SLEEP+20))
13411         log "Sleep ${SLEEP} sec"
13412         local SEC=0
13413         while ((SEC<$SLEEP)); do
13414                 echo -n "..."
13415                 sleep 5
13416                 SEC=$((SEC+5))
13417                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13418                 echo -n "$LRU_SIZE"
13419         done
13420         echo ""
13421         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13422         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13423
13424         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13425                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13426                 unlinkmany $DIR/$tdir/f $NR
13427                 return
13428         }
13429
13430         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13431         log "unlink $NR files at $DIR/$tdir"
13432         unlinkmany $DIR/$tdir/f $NR
13433 }
13434 run_test 124a "lru resize ======================================="
13435
13436 get_max_pool_limit()
13437 {
13438         local limit=$($LCTL get_param \
13439                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13440         local max=0
13441         for l in $limit; do
13442                 if [[ $l -gt $max ]]; then
13443                         max=$l
13444                 fi
13445         done
13446         echo $max
13447 }
13448
13449 test_124b() {
13450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13451         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13452                 skip_env "no lru resize on server"
13453
13454         LIMIT=$(get_max_pool_limit)
13455
13456         NR=$(($(default_lru_size)*20))
13457         if [[ $NR -gt $LIMIT ]]; then
13458                 log "Limit lock number by $LIMIT locks"
13459                 NR=$LIMIT
13460         fi
13461
13462         IFree=$(mdsrate_inodes_available)
13463         if [ $IFree -lt $NR ]; then
13464                 log "Limit lock number by $IFree inodes"
13465                 NR=$IFree
13466         fi
13467
13468         lru_resize_disable mdc
13469         test_mkdir -p $DIR/$tdir/disable_lru_resize
13470
13471         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13472         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13473         cancel_lru_locks mdc
13474         stime=`date +%s`
13475         PID=""
13476         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13477         PID="$PID $!"
13478         sleep 2
13479         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13480         PID="$PID $!"
13481         sleep 2
13482         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13483         PID="$PID $!"
13484         wait $PID
13485         etime=`date +%s`
13486         nolruresize_delta=$((etime-stime))
13487         log "ls -la time: $nolruresize_delta seconds"
13488         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13489         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13490
13491         lru_resize_enable mdc
13492         test_mkdir -p $DIR/$tdir/enable_lru_resize
13493
13494         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13495         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13496         cancel_lru_locks mdc
13497         stime=`date +%s`
13498         PID=""
13499         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13500         PID="$PID $!"
13501         sleep 2
13502         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13503         PID="$PID $!"
13504         sleep 2
13505         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13506         PID="$PID $!"
13507         wait $PID
13508         etime=`date +%s`
13509         lruresize_delta=$((etime-stime))
13510         log "ls -la time: $lruresize_delta seconds"
13511         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13512
13513         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13514                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13515         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13516                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13517         else
13518                 log "lru resize performs the same with no lru resize"
13519         fi
13520         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13521 }
13522 run_test 124b "lru resize (performance test) ======================="
13523
13524 test_124c() {
13525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13526         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13527                 skip_env "no lru resize on server"
13528
13529         # cache ununsed locks on client
13530         local nr=100
13531         cancel_lru_locks mdc
13532         test_mkdir $DIR/$tdir
13533         createmany -o $DIR/$tdir/f $nr ||
13534                 error "failed to create $nr files in $DIR/$tdir"
13535         ls -l $DIR/$tdir > /dev/null
13536
13537         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13538         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13539         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13540         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13541         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13542
13543         # set lru_max_age to 1 sec
13544         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13545         echo "sleep $((recalc_p * 2)) seconds..."
13546         sleep $((recalc_p * 2))
13547
13548         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13549         # restore lru_max_age
13550         $LCTL set_param -n $nsdir.lru_max_age $max_age
13551         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13552         unlinkmany $DIR/$tdir/f $nr
13553 }
13554 run_test 124c "LRUR cancel very aged locks"
13555
13556 test_124d() {
13557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13558         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13559                 skip_env "no lru resize on server"
13560
13561         # cache ununsed locks on client
13562         local nr=100
13563
13564         lru_resize_disable mdc
13565         stack_trap "lru_resize_enable mdc" EXIT
13566
13567         cancel_lru_locks mdc
13568
13569         # asynchronous object destroy at MDT could cause bl ast to client
13570         test_mkdir $DIR/$tdir
13571         createmany -o $DIR/$tdir/f $nr ||
13572                 error "failed to create $nr files in $DIR/$tdir"
13573         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13574
13575         ls -l $DIR/$tdir > /dev/null
13576
13577         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13578         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13579         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13580         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13581
13582         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13583
13584         # set lru_max_age to 1 sec
13585         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13586         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13587
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
13593         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13594 }
13595 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13596
13597 test_125() { # 13358
13598         $LCTL get_param -n llite.*.client_type | grep -q local ||
13599                 skip "must run as local client"
13600         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13601                 skip_env "must have acl enabled"
13602         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13603
13604         test_mkdir $DIR/$tdir
13605         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13606         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13607                 error "setfacl $DIR/$tdir failed"
13608         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13609 }
13610 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13611
13612 test_126() { # bug 12829/13455
13613         $GSS && skip_env "must run as gss disabled"
13614         $LCTL get_param -n llite.*.client_type | grep -q local ||
13615                 skip "must run as local client"
13616         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13617
13618         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13619         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13620         rm -f $DIR/$tfile
13621         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13622 }
13623 run_test 126 "check that the fsgid provided by the client is taken into account"
13624
13625 test_127a() { # bug 15521
13626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13627         local name count samp unit min max sum sumsq
13628
13629         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13630         echo "stats before reset"
13631         $LCTL get_param osc.*.stats
13632         $LCTL set_param osc.*.stats=0
13633         local fsize=$((2048 * 1024))
13634
13635         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13636         cancel_lru_locks osc
13637         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13638
13639         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13640         stack_trap "rm -f $TMP/$tfile.tmp"
13641         while read name count samp unit min max sum sumsq; do
13642                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13643                 [ ! $min ] && error "Missing min value for $name proc entry"
13644                 eval $name=$count || error "Wrong proc format"
13645
13646                 case $name in
13647                 read_bytes|write_bytes)
13648                         [[ "$unit" =~ "bytes" ]] ||
13649                                 error "unit is not 'bytes': $unit"
13650                         (( $min >= 4096 )) || error "min is too small: $min"
13651                         (( $min <= $fsize )) || error "min is too big: $min"
13652                         (( $max >= 4096 )) || error "max is too small: $max"
13653                         (( $max <= $fsize )) || error "max is too big: $max"
13654                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13655                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13656                                 error "sumsquare is too small: $sumsq"
13657                         (( $sumsq <= $fsize * $fsize )) ||
13658                                 error "sumsquare is too big: $sumsq"
13659                         ;;
13660                 ost_read|ost_write)
13661                         [[ "$unit" =~ "usec" ]] ||
13662                                 error "unit is not 'usec': $unit"
13663                         ;;
13664                 *)      ;;
13665                 esac
13666         done < $DIR/$tfile.tmp
13667
13668         #check that we actually got some stats
13669         [ "$read_bytes" ] || error "Missing read_bytes stats"
13670         [ "$write_bytes" ] || error "Missing write_bytes stats"
13671         [ "$read_bytes" != 0 ] || error "no read done"
13672         [ "$write_bytes" != 0 ] || error "no write done"
13673 }
13674 run_test 127a "verify the client stats are sane"
13675
13676 test_127b() { # bug LU-333
13677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13678         local name count samp unit min max sum sumsq
13679
13680         echo "stats before reset"
13681         $LCTL get_param llite.*.stats
13682         $LCTL set_param llite.*.stats=0
13683
13684         # perform 2 reads and writes so MAX is different from SUM.
13685         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13686         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13687         cancel_lru_locks osc
13688         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13689         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13690
13691         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13692         stack_trap "rm -f $TMP/$tfile.tmp"
13693         while read name count samp unit min max sum sumsq; do
13694                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13695                 eval $name=$count || error "Wrong proc format"
13696
13697                 case $name in
13698                 read_bytes|write_bytes)
13699                         [[ "$unit" =~ "bytes" ]] ||
13700                                 error "unit is not 'bytes': $unit"
13701                         (( $count == 2 )) || error "count is not 2: $count"
13702                         (( $min == $PAGE_SIZE )) ||
13703                                 error "min is not $PAGE_SIZE: $min"
13704                         (( $max == $PAGE_SIZE )) ||
13705                                 error "max is not $PAGE_SIZE: $max"
13706                         (( $sum == $PAGE_SIZE * 2 )) ||
13707                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13708                         ;;
13709                 read|write)
13710                         [[ "$unit" =~ "usec" ]] ||
13711                                 error "unit is not 'usec': $unit"
13712                         ;;
13713                 *)      ;;
13714                 esac
13715         done < $TMP/$tfile.tmp
13716
13717         #check that we actually got some stats
13718         [ "$read_bytes" ] || error "Missing read_bytes stats"
13719         [ "$write_bytes" ] || error "Missing write_bytes stats"
13720         [ "$read_bytes" != 0 ] || error "no read done"
13721         [ "$write_bytes" != 0 ] || error "no write done"
13722 }
13723 run_test 127b "verify the llite client stats are sane"
13724
13725 test_127c() { # LU-12394
13726         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13727         local size
13728         local bsize
13729         local reads
13730         local writes
13731         local count
13732
13733         $LCTL set_param llite.*.extents_stats=1
13734         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13735
13736         # Use two stripes so there is enough space in default config
13737         $LFS setstripe -c 2 $DIR/$tfile
13738
13739         # Extent stats start at 0-4K and go in power of two buckets
13740         # LL_HIST_START = 12 --> 2^12 = 4K
13741         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13742         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13743         # small configs
13744         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13745                 do
13746                 # Write and read, 2x each, second time at a non-zero offset
13747                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13748                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13749                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13750                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13751                 rm -f $DIR/$tfile
13752         done
13753
13754         $LCTL get_param llite.*.extents_stats
13755
13756         count=2
13757         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13758                 do
13759                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13760                                 grep -m 1 $bsize)
13761                 reads=$(echo $bucket | awk '{print $5}')
13762                 writes=$(echo $bucket | awk '{print $9}')
13763                 [ "$reads" -eq $count ] ||
13764                         error "$reads reads in < $bsize bucket, expect $count"
13765                 [ "$writes" -eq $count ] ||
13766                         error "$writes writes in < $bsize bucket, expect $count"
13767         done
13768
13769         # Test mmap write and read
13770         $LCTL set_param llite.*.extents_stats=c
13771         size=512
13772         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13773         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13774         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13775
13776         $LCTL get_param llite.*.extents_stats
13777
13778         count=$(((size*1024) / PAGE_SIZE))
13779
13780         bsize=$((2 * PAGE_SIZE / 1024))K
13781
13782         bucket=$($LCTL get_param -n llite.*.extents_stats |
13783                         grep -m 1 $bsize)
13784         reads=$(echo $bucket | awk '{print $5}')
13785         writes=$(echo $bucket | awk '{print $9}')
13786         # mmap writes fault in the page first, creating an additonal read
13787         [ "$reads" -eq $((2 * count)) ] ||
13788                 error "$reads reads in < $bsize bucket, expect $count"
13789         [ "$writes" -eq $count ] ||
13790                 error "$writes writes in < $bsize bucket, expect $count"
13791 }
13792 run_test 127c "test llite extent stats with regular & mmap i/o"
13793
13794 test_128() { # bug 15212
13795         touch $DIR/$tfile
13796         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13797                 find $DIR/$tfile
13798                 find $DIR/$tfile
13799         EOF
13800
13801         result=$(grep error $TMP/$tfile.log)
13802         rm -f $DIR/$tfile $TMP/$tfile.log
13803         [ -z "$result" ] ||
13804                 error "consecutive find's under interactive lfs failed"
13805 }
13806 run_test 128 "interactive lfs for 2 consecutive find's"
13807
13808 set_dir_limits () {
13809         local mntdev
13810         local canondev
13811         local node
13812
13813         local ldproc=/proc/fs/ldiskfs
13814         local facets=$(get_facets MDS)
13815
13816         for facet in ${facets//,/ }; do
13817                 canondev=$(ldiskfs_canon \
13818                            *.$(convert_facet2label $facet).mntdev $facet)
13819                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13820                         ldproc=/sys/fs/ldiskfs
13821                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13822                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13823         done
13824 }
13825
13826 check_mds_dmesg() {
13827         local facets=$(get_facets MDS)
13828         for facet in ${facets//,/ }; do
13829                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13830         done
13831         return 1
13832 }
13833
13834 test_129() {
13835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13836         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13837                 skip "Need MDS version with at least 2.5.56"
13838         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13839                 skip_env "ldiskfs only test"
13840         fi
13841         remote_mds_nodsh && skip "remote MDS with nodsh"
13842
13843         local ENOSPC=28
13844         local has_warning=false
13845
13846         rm -rf $DIR/$tdir
13847         mkdir -p $DIR/$tdir
13848
13849         # block size of mds1
13850         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13851         set_dir_limits $maxsize $((maxsize * 6 / 8))
13852         stack_trap "set_dir_limits 0 0"
13853         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13854         local dirsize=$(stat -c%s "$DIR/$tdir")
13855         local nfiles=0
13856         while (( $dirsize <= $maxsize )); do
13857                 $MCREATE $DIR/$tdir/file_base_$nfiles
13858                 rc=$?
13859                 # check two errors:
13860                 # ENOSPC for ext4 max_dir_size, which has been used since
13861                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13862                 if (( rc == ENOSPC )); then
13863                         set_dir_limits 0 0
13864                         echo "rc=$rc returned as expected after $nfiles files"
13865
13866                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13867                                 error "create failed w/o dir size limit"
13868
13869                         # messages may be rate limited if test is run repeatedly
13870                         check_mds_dmesg '"is approaching max"' ||
13871                                 echo "warning message should be output"
13872                         check_mds_dmesg '"has reached max"' ||
13873                                 echo "reached message should be output"
13874
13875                         dirsize=$(stat -c%s "$DIR/$tdir")
13876
13877                         [[ $dirsize -ge $maxsize ]] && return 0
13878                         error "dirsize $dirsize < $maxsize after $nfiles files"
13879                 elif (( rc != 0 )); then
13880                         break
13881                 fi
13882                 nfiles=$((nfiles + 1))
13883                 dirsize=$(stat -c%s "$DIR/$tdir")
13884         done
13885
13886         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13887 }
13888 run_test 129 "test directory size limit ========================"
13889
13890 OLDIFS="$IFS"
13891 cleanup_130() {
13892         trap 0
13893         IFS="$OLDIFS"
13894 }
13895
13896 test_130a() {
13897         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13898         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13899
13900         trap cleanup_130 EXIT RETURN
13901
13902         local fm_file=$DIR/$tfile
13903         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13904         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13905                 error "dd failed for $fm_file"
13906
13907         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13908         filefrag -ves $fm_file
13909         local rc=$?
13910         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13911                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13912         (( $rc == 0 )) || error "filefrag $fm_file failed"
13913
13914         filefrag_op=$(filefrag -ve -k $fm_file |
13915                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13916         local lun=$($LFS getstripe -i $fm_file)
13917
13918         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13919         IFS=$'\n'
13920         local tot_len=0
13921         for line in $filefrag_op; do
13922                 local frag_lun=$(echo $line | cut -d: -f5)
13923                 local ext_len=$(echo $line | cut -d: -f4)
13924
13925                 if (( $frag_lun != $lun )); then
13926                         error "FIEMAP on 1-stripe file($fm_file) failed"
13927                         return
13928                 fi
13929                 (( tot_len += ext_len ))
13930         done
13931
13932         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13933                 error "FIEMAP on 1-stripe file($fm_file) failed"
13934                 return
13935         fi
13936
13937         echo "FIEMAP on single striped file succeeded"
13938 }
13939 run_test 130a "FIEMAP (1-stripe file)"
13940
13941 test_130b() {
13942         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13943
13944         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13945         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13946         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13947                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13948
13949         trap cleanup_130 EXIT RETURN
13950
13951         local fm_file=$DIR/$tfile
13952         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13953                 error "setstripe on $fm_file"
13954
13955         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13956                 error "dd failed on $fm_file"
13957
13958         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13959         filefrag_op=$(filefrag -ve -k $fm_file |
13960                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13961
13962         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
13963                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13964
13965         IFS=$'\n'
13966         local tot_len=0
13967         local num_luns=1
13968
13969         for line in $filefrag_op; do
13970                 local frag_lun=$(echo $line | cut -d: -f5 |
13971                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13972                 local ext_len=$(echo $line | cut -d: -f4)
13973                 if (( $frag_lun != $last_lun )); then
13974                         if (( tot_len != 1024 )); then
13975                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
13976                                 return
13977                         else
13978                                 (( num_luns += 1 ))
13979                                 tot_len=0
13980                         fi
13981                 fi
13982                 (( tot_len += ext_len ))
13983                 last_lun=$frag_lun
13984         done
13985         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13986                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
13987                 return
13988         fi
13989
13990         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13991 }
13992 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13993
13994 test_130c() {
13995         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13996
13997         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13998         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13999         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14000                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14001
14002         trap cleanup_130 EXIT RETURN
14003
14004         local fm_file=$DIR/$tfile
14005         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14006
14007         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14008                 error "dd failed on $fm_file"
14009
14010         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14011         filefrag_op=$(filefrag -ve -k $fm_file |
14012                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14013
14014         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14015                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14016
14017         IFS=$'\n'
14018         local tot_len=0
14019         local num_luns=1
14020         for line in $filefrag_op; do
14021                 local frag_lun=$(echo $line | cut -d: -f5 |
14022                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14023                 local ext_len=$(echo $line | cut -d: -f4)
14024                 if (( $frag_lun != $last_lun )); then
14025                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14026                         if (( logical != 512 )); then
14027                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14028                                 return
14029                         fi
14030                         if (( tot_len != 512 )); then
14031                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14032                                 return
14033                         else
14034                                 (( num_luns += 1 ))
14035                                 tot_len=0
14036                         fi
14037                 fi
14038                 (( tot_len += ext_len ))
14039                 last_lun=$frag_lun
14040         done
14041         if (( num_luns != 2 || tot_len != 512 )); then
14042                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14043                 return
14044         fi
14045
14046         echo "FIEMAP on 2-stripe file with hole succeeded"
14047 }
14048 run_test 130c "FIEMAP (2-stripe file with hole)"
14049
14050 test_130d() {
14051         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14052
14053         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14054         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14055         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14056                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14057
14058         trap cleanup_130 EXIT RETURN
14059
14060         local fm_file=$DIR/$tfile
14061         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14062                         error "setstripe on $fm_file"
14063
14064         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14065         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14066                 error "dd failed on $fm_file"
14067
14068         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14069         filefrag_op=$(filefrag -ve -k $fm_file |
14070                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14071
14072         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14073                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14074
14075         IFS=$'\n'
14076         local tot_len=0
14077         local num_luns=1
14078         for line in $filefrag_op; do
14079                 local frag_lun=$(echo $line | cut -d: -f5 |
14080                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14081                 local ext_len=$(echo $line | cut -d: -f4)
14082                 if (( $frag_lun != $last_lun )); then
14083                         if (( tot_len != 1024 )); then
14084                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14085                                 return
14086                         else
14087                                 (( num_luns += 1 ))
14088                                 local tot_len=0
14089                         fi
14090                 fi
14091                 (( tot_len += ext_len ))
14092                 last_lun=$frag_lun
14093         done
14094         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14095                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14096                 return
14097         fi
14098
14099         echo "FIEMAP on N-stripe file succeeded"
14100 }
14101 run_test 130d "FIEMAP (N-stripe file)"
14102
14103 test_130e() {
14104         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14105
14106         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14107         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14108         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14109                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14110
14111         trap cleanup_130 EXIT RETURN
14112
14113         local fm_file=$DIR/$tfile
14114         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14115
14116         local num_blks=512
14117         local expected_len=$(( (num_blks / 2) * 64 ))
14118         for ((i = 0; i < $num_blks; i++)); do
14119                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14120                         conv=notrunc > /dev/null 2>&1
14121         done
14122
14123         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14124         filefrag_op=$(filefrag -ve -k $fm_file |
14125                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14126
14127         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14128
14129         IFS=$'\n'
14130         local tot_len=0
14131         local num_luns=1
14132         for line in $filefrag_op; do
14133                 local frag_lun=$(echo $line | cut -d: -f5)
14134                 local ext_len=$(echo $line | cut -d: -f4)
14135                 if (( $frag_lun != $last_lun )); then
14136                         if (( tot_len != $expected_len )); then
14137                                 error "OST$last_lun $tot_len != $expected_len"
14138                         else
14139                                 (( num_luns += 1 ))
14140                                 tot_len=0
14141                         fi
14142                 fi
14143                 (( tot_len += ext_len ))
14144                 last_lun=$frag_lun
14145         done
14146         if (( num_luns != 2 || tot_len != $expected_len )); then
14147                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14148         fi
14149
14150         echo "FIEMAP with continuation calls succeeded"
14151 }
14152 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14153
14154 test_130f() {
14155         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14156         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14157         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14158                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14159
14160         local fm_file=$DIR/$tfile
14161         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14162                 error "multiop create with lov_delay_create on $fm_file"
14163
14164         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14165         filefrag_extents=$(filefrag -vek $fm_file |
14166                            awk '/extents? found/ { print $2 }')
14167         if (( $filefrag_extents != 0 )); then
14168                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14169         fi
14170
14171         rm -f $fm_file
14172 }
14173 run_test 130f "FIEMAP (unstriped file)"
14174
14175 test_130g() {
14176         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14177                 skip "Need MDS version with at least 2.12.53 for overstriping"
14178         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14179         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14180         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14181                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14182
14183         local file=$DIR/$tfile
14184         local nr=$((OSTCOUNT * 100))
14185
14186         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14187
14188         stack_trap "rm -f $file"
14189         dd if=/dev/zero of=$file count=$nr bs=1M
14190         sync
14191         nr=$($LFS getstripe -c $file)
14192
14193         local extents=$(filefrag -v $file |
14194                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14195
14196         echo "filefrag list $extents extents in file with stripecount $nr"
14197         if (( extents < nr )); then
14198                 $LFS getstripe $file
14199                 filefrag -v $file
14200                 error "filefrag printed $extents < $nr extents"
14201         fi
14202 }
14203 run_test 130g "FIEMAP (overstripe file)"
14204
14205 # Test for writev/readv
14206 test_131a() {
14207         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14208                 error "writev test failed"
14209         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14210                 error "readv failed"
14211         rm -f $DIR/$tfile
14212 }
14213 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14214
14215 test_131b() {
14216         local fsize=$((524288 + 1048576 + 1572864))
14217         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14218                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14219                         error "append writev test failed"
14220
14221         ((fsize += 1572864 + 1048576))
14222         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14223                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14224                         error "append writev test failed"
14225         rm -f $DIR/$tfile
14226 }
14227 run_test 131b "test append writev"
14228
14229 test_131c() {
14230         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14231         error "NOT PASS"
14232 }
14233 run_test 131c "test read/write on file w/o objects"
14234
14235 test_131d() {
14236         rwv -f $DIR/$tfile -w -n 1 1572864
14237         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14238         if [ "$NOB" != 1572864 ]; then
14239                 error "Short read filed: read $NOB bytes instead of 1572864"
14240         fi
14241         rm -f $DIR/$tfile
14242 }
14243 run_test 131d "test short read"
14244
14245 test_131e() {
14246         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14247         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14248         error "read hitting hole failed"
14249         rm -f $DIR/$tfile
14250 }
14251 run_test 131e "test read hitting hole"
14252
14253 check_stats() {
14254         local facet=$1
14255         local op=$2
14256         local want=${3:-0}
14257         local res
14258
14259         # open             11 samples [usecs] 468 4793 13658 35791898
14260         case $facet in
14261         mds*) res=($(do_facet $facet \
14262                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14263                  ;;
14264         ost*) res=($(do_facet $facet \
14265                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14266                  ;;
14267         *) error "Wrong facet '$facet'" ;;
14268         esac
14269         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14270         # if $want is zero, it means any stat increment is ok.
14271         if (( $want > 0 )); then
14272                 local count=${res[1]}
14273
14274                 if (( $count != $want )); then
14275                         if [[ $facet =~ "mds" ]]; then
14276                                 do_nodes $(comma_list $(mdts_nodes)) \
14277                                         $LCTL get_param mdt.*.md_stats
14278                         else
14279                                 do_nodes $(comma_list $(osts-nodes)) \
14280                                         $LCTL get_param obdfilter.*.stats
14281                         fi
14282                         error "The $op counter on $facet is $count, not $want"
14283                 fi
14284         fi
14285 }
14286
14287 test_133a() {
14288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14289         remote_ost_nodsh && skip "remote OST with nodsh"
14290         remote_mds_nodsh && skip "remote MDS with nodsh"
14291         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14292                 skip_env "MDS doesn't support rename stats"
14293
14294         local testdir=$DIR/${tdir}/stats_testdir
14295
14296         mkdir -p $DIR/${tdir}
14297
14298         # clear stats.
14299         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14300         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14301
14302         # verify mdt stats first.
14303         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14304         check_stats $SINGLEMDS "mkdir" 1
14305
14306         # clear "open" from "lfs mkdir" above
14307         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14308         touch ${testdir}/${tfile} || error "touch failed"
14309         check_stats $SINGLEMDS "open" 1
14310         check_stats $SINGLEMDS "close" 1
14311         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14312                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14313                 check_stats $SINGLEMDS "mknod" 2
14314         }
14315         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14316         check_stats $SINGLEMDS "unlink" 1
14317         rm -f ${testdir}/${tfile} || error "file remove failed"
14318         check_stats $SINGLEMDS "unlink" 2
14319
14320         # remove working dir and check mdt stats again.
14321         rmdir ${testdir} || error "rmdir failed"
14322         check_stats $SINGLEMDS "rmdir" 1
14323
14324         local testdir1=$DIR/${tdir}/stats_testdir1
14325         mkdir -p ${testdir}
14326         mkdir -p ${testdir1}
14327         touch ${testdir1}/test1
14328         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14329         check_stats $SINGLEMDS "crossdir_rename" 1
14330
14331         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14332         check_stats $SINGLEMDS "samedir_rename" 1
14333
14334         rm -rf $DIR/${tdir}
14335 }
14336 run_test 133a "Verifying MDT stats ========================================"
14337
14338 test_133b() {
14339         local res
14340
14341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14342         remote_ost_nodsh && skip "remote OST with nodsh"
14343         remote_mds_nodsh && skip "remote MDS with nodsh"
14344
14345         local testdir=$DIR/${tdir}/stats_testdir
14346
14347         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14348         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14349         touch ${testdir}/${tfile} || error "touch failed"
14350         cancel_lru_locks mdc
14351
14352         # clear stats.
14353         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14354         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14355
14356         # extra mdt stats verification.
14357         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14358         check_stats $SINGLEMDS "setattr" 1
14359         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14360         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14361         then            # LU-1740
14362                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14363                 check_stats $SINGLEMDS "getattr" 1
14364         fi
14365         rm -rf $DIR/${tdir}
14366
14367         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14368         # so the check below is not reliable
14369         [ $MDSCOUNT -eq 1 ] || return 0
14370
14371         # Sleep to avoid a cached response.
14372         #define OBD_STATFS_CACHE_SECONDS 1
14373         sleep 2
14374         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14375         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14376         $LFS df || error "lfs failed"
14377         check_stats $SINGLEMDS "statfs" 1
14378
14379         # check aggregated statfs (LU-10018)
14380         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14381                 return 0
14382         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14383                 return 0
14384         sleep 2
14385         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14386         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14387         df $DIR
14388         check_stats $SINGLEMDS "statfs" 1
14389
14390         # We want to check that the client didn't send OST_STATFS to
14391         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14392         # extra care is needed here.
14393         if remote_mds; then
14394                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14395                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14396
14397                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14398                 [ "$res" ] && error "OST got STATFS"
14399         fi
14400
14401         return 0
14402 }
14403 run_test 133b "Verifying extra MDT stats =================================="
14404
14405 test_133c() {
14406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14407         remote_ost_nodsh && skip "remote OST with nodsh"
14408         remote_mds_nodsh && skip "remote MDS with nodsh"
14409
14410         local testdir=$DIR/$tdir/stats_testdir
14411
14412         test_mkdir -p $testdir
14413
14414         # verify obdfilter stats.
14415         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14416         sync
14417         cancel_lru_locks osc
14418         wait_delete_completed
14419
14420         # clear stats.
14421         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14422         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14423
14424         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14425                 error "dd failed"
14426         sync
14427         cancel_lru_locks osc
14428         check_stats ost1 "write" 1
14429
14430         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14431         check_stats ost1 "read" 1
14432
14433         > $testdir/$tfile || error "truncate failed"
14434         check_stats ost1 "punch" 1
14435
14436         rm -f $testdir/$tfile || error "file remove failed"
14437         wait_delete_completed
14438         check_stats ost1 "destroy" 1
14439
14440         rm -rf $DIR/$tdir
14441 }
14442 run_test 133c "Verifying OST stats ========================================"
14443
14444 order_2() {
14445         local value=$1
14446         local orig=$value
14447         local order=1
14448
14449         while [ $value -ge 2 ]; do
14450                 order=$((order*2))
14451                 value=$((value/2))
14452         done
14453
14454         if [ $orig -gt $order ]; then
14455                 order=$((order*2))
14456         fi
14457         echo $order
14458 }
14459
14460 size_in_KMGT() {
14461     local value=$1
14462     local size=('K' 'M' 'G' 'T');
14463     local i=0
14464     local size_string=$value
14465
14466     while [ $value -ge 1024 ]; do
14467         if [ $i -gt 3 ]; then
14468             #T is the biggest unit we get here, if that is bigger,
14469             #just return XXXT
14470             size_string=${value}T
14471             break
14472         fi
14473         value=$((value >> 10))
14474         if [ $value -lt 1024 ]; then
14475             size_string=${value}${size[$i]}
14476             break
14477         fi
14478         i=$((i + 1))
14479     done
14480
14481     echo $size_string
14482 }
14483
14484 get_rename_size() {
14485         local size=$1
14486         local context=${2:-.}
14487         local sample=$(do_facet $SINGLEMDS $LCTL \
14488                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14489                 grep -A1 $context |
14490                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14491         echo $sample
14492 }
14493
14494 test_133d() {
14495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14496         remote_ost_nodsh && skip "remote OST with nodsh"
14497         remote_mds_nodsh && skip "remote MDS with nodsh"
14498         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14499                 skip_env "MDS doesn't support rename stats"
14500
14501         local testdir1=$DIR/${tdir}/stats_testdir1
14502         local testdir2=$DIR/${tdir}/stats_testdir2
14503         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14504
14505         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14506
14507         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14508         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14509
14510         createmany -o $testdir1/test 512 || error "createmany failed"
14511
14512         # check samedir rename size
14513         mv ${testdir1}/test0 ${testdir1}/test_0
14514
14515         local testdir1_size=$(ls -l $DIR/${tdir} |
14516                 awk '/stats_testdir1/ {print $5}')
14517         local testdir2_size=$(ls -l $DIR/${tdir} |
14518                 awk '/stats_testdir2/ {print $5}')
14519
14520         testdir1_size=$(order_2 $testdir1_size)
14521         testdir2_size=$(order_2 $testdir2_size)
14522
14523         testdir1_size=$(size_in_KMGT $testdir1_size)
14524         testdir2_size=$(size_in_KMGT $testdir2_size)
14525
14526         echo "source rename dir size: ${testdir1_size}"
14527         echo "target rename dir size: ${testdir2_size}"
14528
14529         local cmd="do_facet $SINGLEMDS $LCTL "
14530         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14531
14532         eval $cmd || error "$cmd failed"
14533         local samedir=$($cmd | grep 'same_dir')
14534         local same_sample=$(get_rename_size $testdir1_size)
14535         [ -z "$samedir" ] && error "samedir_rename_size count error"
14536         [[ $same_sample -eq 1 ]] ||
14537                 error "samedir_rename_size error $same_sample"
14538         echo "Check same dir rename stats success"
14539
14540         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14541
14542         # check crossdir rename size
14543         mv ${testdir1}/test_0 ${testdir2}/test_0
14544
14545         testdir1_size=$(ls -l $DIR/${tdir} |
14546                 awk '/stats_testdir1/ {print $5}')
14547         testdir2_size=$(ls -l $DIR/${tdir} |
14548                 awk '/stats_testdir2/ {print $5}')
14549
14550         testdir1_size=$(order_2 $testdir1_size)
14551         testdir2_size=$(order_2 $testdir2_size)
14552
14553         testdir1_size=$(size_in_KMGT $testdir1_size)
14554         testdir2_size=$(size_in_KMGT $testdir2_size)
14555
14556         echo "source rename dir size: ${testdir1_size}"
14557         echo "target rename dir size: ${testdir2_size}"
14558
14559         eval $cmd || error "$cmd failed"
14560         local crossdir=$($cmd | grep 'crossdir')
14561         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14562         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14563         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14564         [[ $src_sample -eq 1 ]] ||
14565                 error "crossdir_rename_size error $src_sample"
14566         [[ $tgt_sample -eq 1 ]] ||
14567                 error "crossdir_rename_size error $tgt_sample"
14568         echo "Check cross dir rename stats success"
14569         rm -rf $DIR/${tdir}
14570 }
14571 run_test 133d "Verifying rename_stats ========================================"
14572
14573 test_133e() {
14574         remote_mds_nodsh && skip "remote MDS with nodsh"
14575         remote_ost_nodsh && skip "remote OST with nodsh"
14576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14577
14578         local testdir=$DIR/${tdir}/stats_testdir
14579         local ctr f0 f1 bs=32768 count=42 sum
14580
14581         mkdir -p ${testdir} || error "mkdir failed"
14582
14583         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14584
14585         for ctr in {write,read}_bytes; do
14586                 sync
14587                 cancel_lru_locks osc
14588
14589                 do_facet ost1 $LCTL set_param -n \
14590                         "obdfilter.*.exports.clear=clear"
14591
14592                 if [ $ctr = write_bytes ]; then
14593                         f0=/dev/zero
14594                         f1=${testdir}/${tfile}
14595                 else
14596                         f0=${testdir}/${tfile}
14597                         f1=/dev/null
14598                 fi
14599
14600                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14601                         error "dd failed"
14602                 sync
14603                 cancel_lru_locks osc
14604
14605                 sum=$(do_facet ost1 $LCTL get_param \
14606                         "obdfilter.*.exports.*.stats" |
14607                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14608                                 $1 == ctr { sum += $7 }
14609                                 END { printf("%0.0f", sum) }')
14610
14611                 if ((sum != bs * count)); then
14612                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14613                 fi
14614         done
14615
14616         rm -rf $DIR/${tdir}
14617 }
14618 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14619
14620 test_133f() {
14621         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14622                 skip "too old lustre for get_param -R ($facet_ver)"
14623
14624         # verifying readability.
14625         $LCTL get_param -R '*' &> /dev/null
14626
14627         # Verifing writability with badarea_io.
14628         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14629         local skipped_params='force_lbug|changelog_mask|daemon_file'
14630         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14631                 egrep -v "$skipped_params" |
14632                 xargs -n 1 find $proc_dirs -name |
14633                 xargs -n 1 badarea_io ||
14634                 error "client badarea_io failed"
14635
14636         # remount the FS in case writes/reads /proc break the FS
14637         cleanup || error "failed to unmount"
14638         setup || error "failed to setup"
14639 }
14640 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14641
14642 test_133g() {
14643         remote_mds_nodsh && skip "remote MDS with nodsh"
14644         remote_ost_nodsh && skip "remote OST with nodsh"
14645
14646         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14647         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14648         local facet
14649         for facet in mds1 ost1; do
14650                 local facet_ver=$(lustre_version_code $facet)
14651                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14652                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14653                 else
14654                         log "$facet: too old lustre for get_param -R"
14655                 fi
14656                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14657                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14658                                 tr -d = | egrep -v $skipped_params |
14659                                 xargs -n 1 find $proc_dirs -name |
14660                                 xargs -n 1 badarea_io" ||
14661                                         error "$facet badarea_io failed"
14662                 else
14663                         skip_noexit "$facet: too old lustre for get_param -R"
14664                 fi
14665         done
14666
14667         # remount the FS in case writes/reads /proc break the FS
14668         cleanup || error "failed to unmount"
14669         setup || error "failed to setup"
14670 }
14671 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14672
14673 test_133h() {
14674         remote_mds_nodsh && skip "remote MDS with nodsh"
14675         remote_ost_nodsh && skip "remote OST with nodsh"
14676         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14677                 skip "Need MDS version at least 2.9.54"
14678
14679         local facet
14680         for facet in client mds1 ost1; do
14681                 # Get the list of files that are missing the terminating newline
14682                 local plist=$(do_facet $facet
14683                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14684                 local ent
14685                 for ent in $plist; do
14686                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14687                                 awk -v FS='\v' -v RS='\v\v' \
14688                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14689                                         print FILENAME}'" 2>/dev/null)
14690                         [ -z $missing ] || {
14691                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14692                                 error "file does not end with newline: $facet-$ent"
14693                         }
14694                 done
14695         done
14696 }
14697 run_test 133h "Proc files should end with newlines"
14698
14699 test_134a() {
14700         remote_mds_nodsh && skip "remote MDS with nodsh"
14701         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14702                 skip "Need MDS version at least 2.7.54"
14703
14704         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14705         cancel_lru_locks mdc
14706
14707         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14708         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14709         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14710
14711         local nr=1000
14712         createmany -o $DIR/$tdir/f $nr ||
14713                 error "failed to create $nr files in $DIR/$tdir"
14714         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14715
14716         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14717         do_facet mds1 $LCTL set_param fail_loc=0x327
14718         do_facet mds1 $LCTL set_param fail_val=500
14719         touch $DIR/$tdir/m
14720
14721         echo "sleep 10 seconds ..."
14722         sleep 10
14723         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14724
14725         do_facet mds1 $LCTL set_param fail_loc=0
14726         do_facet mds1 $LCTL set_param fail_val=0
14727         [ $lck_cnt -lt $unused ] ||
14728                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14729
14730         rm $DIR/$tdir/m
14731         unlinkmany $DIR/$tdir/f $nr
14732 }
14733 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14734
14735 test_134b() {
14736         remote_mds_nodsh && skip "remote MDS with nodsh"
14737         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14738                 skip "Need MDS version at least 2.7.54"
14739
14740         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14741         cancel_lru_locks mdc
14742
14743         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14744                         ldlm.lock_reclaim_threshold_mb)
14745         # disable reclaim temporarily
14746         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14747
14748         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14749         do_facet mds1 $LCTL set_param fail_loc=0x328
14750         do_facet mds1 $LCTL set_param fail_val=500
14751
14752         $LCTL set_param debug=+trace
14753
14754         local nr=600
14755         createmany -o $DIR/$tdir/f $nr &
14756         local create_pid=$!
14757
14758         echo "Sleep $TIMEOUT seconds ..."
14759         sleep $TIMEOUT
14760         if ! ps -p $create_pid  > /dev/null 2>&1; then
14761                 do_facet mds1 $LCTL set_param fail_loc=0
14762                 do_facet mds1 $LCTL set_param fail_val=0
14763                 do_facet mds1 $LCTL set_param \
14764                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14765                 error "createmany finished incorrectly!"
14766         fi
14767         do_facet mds1 $LCTL set_param fail_loc=0
14768         do_facet mds1 $LCTL set_param fail_val=0
14769         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14770         wait $create_pid || return 1
14771
14772         unlinkmany $DIR/$tdir/f $nr
14773 }
14774 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14775
14776 test_135() {
14777         remote_mds_nodsh && skip "remote MDS with nodsh"
14778         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14779                 skip "Need MDS version at least 2.13.50"
14780         local fname
14781
14782         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14783
14784 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14785         #set only one record at plain llog
14786         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14787
14788         #fill already existed plain llog each 64767
14789         #wrapping whole catalog
14790         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14791
14792         createmany -o $DIR/$tdir/$tfile_ 64700
14793         for (( i = 0; i < 64700; i = i + 2 ))
14794         do
14795                 rm $DIR/$tdir/$tfile_$i &
14796                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14797                 local pid=$!
14798                 wait $pid
14799         done
14800
14801         #waiting osp synchronization
14802         wait_delete_completed
14803 }
14804 run_test 135 "Race catalog processing"
14805
14806 test_136() {
14807         remote_mds_nodsh && skip "remote MDS with nodsh"
14808         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14809                 skip "Need MDS version at least 2.13.50"
14810         local fname
14811
14812         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14813         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14814         #set only one record at plain llog
14815 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14816         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14817
14818         #fill already existed 2 plain llogs each 64767
14819         #wrapping whole catalog
14820         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14821         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14822         wait_delete_completed
14823
14824         createmany -o $DIR/$tdir/$tfile_ 10
14825         sleep 25
14826
14827         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14828         for (( i = 0; i < 10; i = i + 3 ))
14829         do
14830                 rm $DIR/$tdir/$tfile_$i &
14831                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14832                 local pid=$!
14833                 wait $pid
14834                 sleep 7
14835                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14836         done
14837
14838         #waiting osp synchronization
14839         wait_delete_completed
14840 }
14841 run_test 136 "Race catalog processing 2"
14842
14843 test_140() { #bug-17379
14844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14845
14846         test_mkdir $DIR/$tdir
14847         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14848         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14849
14850         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14851         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14852         local i=0
14853         while i=$((i + 1)); do
14854                 test_mkdir $i
14855                 cd $i || error "Changing to $i"
14856                 ln -s ../stat stat || error "Creating stat symlink"
14857                 # Read the symlink until ELOOP present,
14858                 # not LBUGing the system is considered success,
14859                 # we didn't overrun the stack.
14860                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14861                 if [ $ret -ne 0 ]; then
14862                         if [ $ret -eq 40 ]; then
14863                                 break  # -ELOOP
14864                         else
14865                                 error "Open stat symlink"
14866                                         return
14867                         fi
14868                 fi
14869         done
14870         i=$((i - 1))
14871         echo "The symlink depth = $i"
14872         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14873                 error "Invalid symlink depth"
14874
14875         # Test recursive symlink
14876         ln -s symlink_self symlink_self
14877         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14878         echo "open symlink_self returns $ret"
14879         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14880 }
14881 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14882
14883 test_150a() {
14884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14885
14886         local TF="$TMP/$tfile"
14887
14888         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14889         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14890         cp $TF $DIR/$tfile
14891         cancel_lru_locks $OSC
14892         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14893         remount_client $MOUNT
14894         df -P $MOUNT
14895         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14896
14897         $TRUNCATE $TF 6000
14898         $TRUNCATE $DIR/$tfile 6000
14899         cancel_lru_locks $OSC
14900         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14901
14902         echo "12345" >>$TF
14903         echo "12345" >>$DIR/$tfile
14904         cancel_lru_locks $OSC
14905         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14906
14907         echo "12345" >>$TF
14908         echo "12345" >>$DIR/$tfile
14909         cancel_lru_locks $OSC
14910         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14911 }
14912 run_test 150a "truncate/append tests"
14913
14914 test_150b() {
14915         check_set_fallocate_or_skip
14916
14917         touch $DIR/$tfile
14918         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14919         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14920 }
14921 run_test 150b "Verify fallocate (prealloc) functionality"
14922
14923 test_150bb() {
14924         check_set_fallocate_or_skip
14925
14926         touch $DIR/$tfile
14927         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14928         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14929         > $DIR/$tfile
14930         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14931         # precomputed md5sum for 20MB of zeroes
14932         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14933         local sum=($(md5sum $DIR/$tfile))
14934
14935         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14936
14937         check_set_fallocate 1
14938
14939         > $DIR/$tfile
14940         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14941         sum=($(md5sum $DIR/$tfile))
14942
14943         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14944 }
14945 run_test 150bb "Verify fallocate modes both zero space"
14946
14947 test_150c() {
14948         check_set_fallocate_or_skip
14949         local striping="-c2"
14950
14951         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14952         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14953         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14954         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14955         local want=$((OSTCOUNT * 1048576))
14956
14957         # Must allocate all requested space, not more than 5% extra
14958         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14959                 error "bytes $bytes is not $want"
14960
14961         rm -f $DIR/$tfile
14962
14963         echo "verify fallocate on PFL file"
14964
14965         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14966
14967         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14968                 error "Create $DIR/$tfile failed"
14969         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14970         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14971         want=$((512 * 1048576))
14972
14973         # Must allocate all requested space, not more than 5% extra
14974         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14975                 error "bytes $bytes is not $want"
14976 }
14977 run_test 150c "Verify fallocate Size and Blocks"
14978
14979 test_150d() {
14980         check_set_fallocate_or_skip
14981         local striping="-c2"
14982
14983         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14984
14985         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14986         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14987                 error "setstripe failed"
14988         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14989         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14990         local want=$((OSTCOUNT * 1048576))
14991
14992         # Must allocate all requested space, not more than 5% extra
14993         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14994                 error "bytes $bytes is not $want"
14995 }
14996 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14997
14998 test_150e() {
14999         check_set_fallocate_or_skip
15000
15001         echo "df before:"
15002         $LFS df
15003         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15004         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15005                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15006
15007         # Find OST with Minimum Size
15008         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15009                        sort -un | head -1)
15010
15011         # Get 100MB per OST of the available space to reduce run time
15012         # else 60% of the available space if we are running SLOW tests
15013         if [ $SLOW == "no" ]; then
15014                 local space=$((1024 * 100 * OSTCOUNT))
15015         else
15016                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15017         fi
15018
15019         fallocate -l${space}k $DIR/$tfile ||
15020                 error "fallocate ${space}k $DIR/$tfile failed"
15021         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15022
15023         # get size immediately after fallocate. This should be correctly
15024         # updated
15025         local size=$(stat -c '%s' $DIR/$tfile)
15026         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15027
15028         # Sleep for a while for statfs to get updated. And not pull from cache.
15029         sleep 2
15030
15031         echo "df after fallocate:"
15032         $LFS df
15033
15034         (( size / 1024 == space )) || error "size $size != requested $space"
15035         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15036                 error "used $used < space $space"
15037
15038         rm $DIR/$tfile || error "rm failed"
15039         sync
15040         wait_delete_completed
15041
15042         echo "df after unlink:"
15043         $LFS df
15044 }
15045 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15046
15047 test_150f() {
15048         local size
15049         local blocks
15050         local want_size_before=20480 # in bytes
15051         local want_blocks_before=40 # 512 sized blocks
15052         local want_blocks_after=24  # 512 sized blocks
15053         local length=$(((want_blocks_before - want_blocks_after) * 512))
15054
15055         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15056                 skip "need at least 2.14.0 for fallocate punch"
15057
15058         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15059                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15060         fi
15061
15062         check_set_fallocate_or_skip
15063         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15064
15065         [[ "x$DOM" == "xyes" ]] &&
15066                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15067
15068         echo "Verify fallocate punch: Range within the file range"
15069         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15070                 error "dd failed for bs 4096 and count 5"
15071
15072         # Call fallocate with punch range which is within the file range
15073         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15074                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15075         # client must see changes immediately after fallocate
15076         size=$(stat -c '%s' $DIR/$tfile)
15077         blocks=$(stat -c '%b' $DIR/$tfile)
15078
15079         # Verify punch worked.
15080         (( blocks == want_blocks_after )) ||
15081                 error "punch failed: blocks $blocks != $want_blocks_after"
15082
15083         (( size == want_size_before )) ||
15084                 error "punch failed: size $size != $want_size_before"
15085
15086         # Verify there is hole in file
15087         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15088         # precomputed md5sum
15089         local expect="4a9a834a2db02452929c0a348273b4aa"
15090
15091         cksum=($(md5sum $DIR/$tfile))
15092         [[ "${cksum[0]}" == "$expect" ]] ||
15093                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15094
15095         # Start second sub-case for fallocate punch.
15096         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15097         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15098                 error "dd failed for bs 4096 and count 5"
15099
15100         # Punch range less than block size will have no change in block count
15101         want_blocks_after=40  # 512 sized blocks
15102
15103         # Punch overlaps two blocks and less than blocksize
15104         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15105                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15106         size=$(stat -c '%s' $DIR/$tfile)
15107         blocks=$(stat -c '%b' $DIR/$tfile)
15108
15109         # Verify punch worked.
15110         (( blocks == want_blocks_after )) ||
15111                 error "punch failed: blocks $blocks != $want_blocks_after"
15112
15113         (( size == want_size_before )) ||
15114                 error "punch failed: size $size != $want_size_before"
15115
15116         # Verify if range is really zero'ed out. We expect Zeros.
15117         # precomputed md5sum
15118         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15119         cksum=($(md5sum $DIR/$tfile))
15120         [[ "${cksum[0]}" == "$expect" ]] ||
15121                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15122 }
15123 run_test 150f "Verify fallocate punch functionality"
15124
15125 test_150g() {
15126         local space
15127         local size
15128         local blocks
15129         local blocks_after
15130         local size_after
15131         local BS=4096 # Block size in bytes
15132
15133         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15134                 skip "need at least 2.14.0 for fallocate punch"
15135
15136         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15137                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15138         fi
15139
15140         check_set_fallocate_or_skip
15141         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15142
15143         if [[ "x$DOM" == "xyes" ]]; then
15144                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15145                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15146         else
15147                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15148                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15149         fi
15150
15151         # Get 100MB per OST of the available space to reduce run time
15152         # else 60% of the available space if we are running SLOW tests
15153         if [ $SLOW == "no" ]; then
15154                 space=$((1024 * 100 * OSTCOUNT))
15155         else
15156                 # Find OST with Minimum Size
15157                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15158                         sort -un | head -1)
15159                 echo "min size OST: $space"
15160                 space=$(((space * 60)/100 * OSTCOUNT))
15161         fi
15162         # space in 1k units, round to 4k blocks
15163         local blkcount=$((space * 1024 / $BS))
15164
15165         echo "Verify fallocate punch: Very large Range"
15166         fallocate -l${space}k $DIR/$tfile ||
15167                 error "fallocate ${space}k $DIR/$tfile failed"
15168         # write 1M at the end, start and in the middle
15169         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15170                 error "dd failed: bs $BS count 256"
15171         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15172                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15173         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15174                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15175
15176         # Gather stats.
15177         size=$(stat -c '%s' $DIR/$tfile)
15178
15179         # gather punch length.
15180         local punch_size=$((size - (BS * 2)))
15181
15182         echo "punch_size = $punch_size"
15183         echo "size - punch_size: $((size - punch_size))"
15184         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15185
15186         # Call fallocate to punch all except 2 blocks. We leave the
15187         # first and the last block
15188         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15189         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15190                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15191
15192         size_after=$(stat -c '%s' $DIR/$tfile)
15193         blocks_after=$(stat -c '%b' $DIR/$tfile)
15194
15195         # Verify punch worked.
15196         # Size should be kept
15197         (( size == size_after )) ||
15198                 error "punch failed: size $size != $size_after"
15199
15200         # two 4k data blocks to remain plus possible 1 extra extent block
15201         (( blocks_after <= ((BS / 512) * 3) )) ||
15202                 error "too many blocks remains: $blocks_after"
15203
15204         # Verify that file has hole between the first and the last blocks
15205         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15206         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15207
15208         echo "Hole at [$hole_start, $hole_end)"
15209         (( hole_start == BS )) ||
15210                 error "no hole at offset $BS after punch"
15211
15212         (( hole_end == BS + punch_size )) ||
15213                 error "data at offset $hole_end < $((BS + punch_size))"
15214 }
15215 run_test 150g "Verify fallocate punch on large range"
15216
15217 #LU-2902 roc_hit was not able to read all values from lproc
15218 function roc_hit_init() {
15219         local list=$(comma_list $(osts_nodes))
15220         local dir=$DIR/$tdir-check
15221         local file=$dir/$tfile
15222         local BEFORE
15223         local AFTER
15224         local idx
15225
15226         test_mkdir $dir
15227         #use setstripe to do a write to every ost
15228         for i in $(seq 0 $((OSTCOUNT-1))); do
15229                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15230                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15231                 idx=$(printf %04x $i)
15232                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15233                         awk '$1 == "cache_access" {sum += $7}
15234                                 END { printf("%0.0f", sum) }')
15235
15236                 cancel_lru_locks osc
15237                 cat $file >/dev/null
15238
15239                 AFTER=$(get_osd_param $list *OST*$idx stats |
15240                         awk '$1 == "cache_access" {sum += $7}
15241                                 END { printf("%0.0f", sum) }')
15242
15243                 echo BEFORE:$BEFORE AFTER:$AFTER
15244                 if ! let "AFTER - BEFORE == 4"; then
15245                         rm -rf $dir
15246                         error "roc_hit is not safe to use"
15247                 fi
15248                 rm $file
15249         done
15250
15251         rm -rf $dir
15252 }
15253
15254 function roc_hit() {
15255         local list=$(comma_list $(osts_nodes))
15256         echo $(get_osd_param $list '' stats |
15257                 awk '$1 == "cache_hit" {sum += $7}
15258                         END { printf("%0.0f", sum) }')
15259 }
15260
15261 function set_cache() {
15262         local on=1
15263
15264         if [ "$2" == "off" ]; then
15265                 on=0;
15266         fi
15267         local list=$(comma_list $(osts_nodes))
15268         set_osd_param $list '' $1_cache_enable $on
15269
15270         cancel_lru_locks osc
15271 }
15272
15273 test_151() {
15274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15275         remote_ost_nodsh && skip "remote OST with nodsh"
15276
15277         local CPAGES=3
15278         local list=$(comma_list $(osts_nodes))
15279
15280         # check whether obdfilter is cache capable at all
15281         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15282                 skip "not cache-capable obdfilter"
15283         fi
15284
15285         # check cache is enabled on all obdfilters
15286         if get_osd_param $list '' read_cache_enable | grep 0; then
15287                 skip "oss cache is disabled"
15288         fi
15289
15290         set_osd_param $list '' writethrough_cache_enable 1
15291
15292         # check write cache is enabled on all obdfilters
15293         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15294                 skip "oss write cache is NOT enabled"
15295         fi
15296
15297         roc_hit_init
15298
15299         #define OBD_FAIL_OBD_NO_LRU  0x609
15300         do_nodes $list $LCTL set_param fail_loc=0x609
15301
15302         # pages should be in the case right after write
15303         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15304                 error "dd failed"
15305
15306         local BEFORE=$(roc_hit)
15307         cancel_lru_locks osc
15308         cat $DIR/$tfile >/dev/null
15309         local AFTER=$(roc_hit)
15310
15311         do_nodes $list $LCTL set_param fail_loc=0
15312
15313         if ! let "AFTER - BEFORE == CPAGES"; then
15314                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15315         fi
15316
15317         cancel_lru_locks osc
15318         # invalidates OST cache
15319         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15320         set_osd_param $list '' read_cache_enable 0
15321         cat $DIR/$tfile >/dev/null
15322
15323         # now data shouldn't be found in the cache
15324         BEFORE=$(roc_hit)
15325         cancel_lru_locks osc
15326         cat $DIR/$tfile >/dev/null
15327         AFTER=$(roc_hit)
15328         if let "AFTER - BEFORE != 0"; then
15329                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15330         fi
15331
15332         set_osd_param $list '' read_cache_enable 1
15333         rm -f $DIR/$tfile
15334 }
15335 run_test 151 "test cache on oss and controls ==============================="
15336
15337 test_152() {
15338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15339
15340         local TF="$TMP/$tfile"
15341
15342         # simulate ENOMEM during write
15343 #define OBD_FAIL_OST_NOMEM      0x226
15344         lctl set_param fail_loc=0x80000226
15345         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15346         cp $TF $DIR/$tfile
15347         sync || error "sync failed"
15348         lctl set_param fail_loc=0
15349
15350         # discard client's cache
15351         cancel_lru_locks osc
15352
15353         # simulate ENOMEM during read
15354         lctl set_param fail_loc=0x80000226
15355         cmp $TF $DIR/$tfile || error "cmp failed"
15356         lctl set_param fail_loc=0
15357
15358         rm -f $TF
15359 }
15360 run_test 152 "test read/write with enomem ============================"
15361
15362 test_153() {
15363         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15364 }
15365 run_test 153 "test if fdatasync does not crash ======================="
15366
15367 dot_lustre_fid_permission_check() {
15368         local fid=$1
15369         local ffid=$MOUNT/.lustre/fid/$fid
15370         local test_dir=$2
15371
15372         echo "stat fid $fid"
15373         stat $ffid || error "stat $ffid failed."
15374         echo "touch fid $fid"
15375         touch $ffid || error "touch $ffid failed."
15376         echo "write to fid $fid"
15377         cat /etc/hosts > $ffid || error "write $ffid failed."
15378         echo "read fid $fid"
15379         diff /etc/hosts $ffid || error "read $ffid failed."
15380         echo "append write to fid $fid"
15381         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15382         echo "rename fid $fid"
15383         mv $ffid $test_dir/$tfile.1 &&
15384                 error "rename $ffid to $tfile.1 should fail."
15385         touch $test_dir/$tfile.1
15386         mv $test_dir/$tfile.1 $ffid &&
15387                 error "rename $tfile.1 to $ffid should fail."
15388         rm -f $test_dir/$tfile.1
15389         echo "truncate fid $fid"
15390         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15391         echo "link fid $fid"
15392         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15393         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15394                 echo "setfacl fid $fid"
15395                 setfacl -R -m u:$USER0:rwx $ffid ||
15396                         error "setfacl $ffid failed"
15397                 echo "getfacl fid $fid"
15398                 getfacl $ffid || error "getfacl $ffid failed."
15399         fi
15400         echo "unlink fid $fid"
15401         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15402         echo "mknod fid $fid"
15403         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15404
15405         fid=[0xf00000400:0x1:0x0]
15406         ffid=$MOUNT/.lustre/fid/$fid
15407
15408         echo "stat non-exist fid $fid"
15409         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15410         echo "write to non-exist fid $fid"
15411         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15412         echo "link new fid $fid"
15413         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15414
15415         mkdir -p $test_dir/$tdir
15416         touch $test_dir/$tdir/$tfile
15417         fid=$($LFS path2fid $test_dir/$tdir)
15418         rc=$?
15419         [ $rc -ne 0 ] &&
15420                 error "error: could not get fid for $test_dir/$dir/$tfile."
15421
15422         ffid=$MOUNT/.lustre/fid/$fid
15423
15424         echo "ls $fid"
15425         ls $ffid || error "ls $ffid failed."
15426         echo "touch $fid/$tfile.1"
15427         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15428
15429         echo "touch $MOUNT/.lustre/fid/$tfile"
15430         touch $MOUNT/.lustre/fid/$tfile && \
15431                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15432
15433         echo "setxattr to $MOUNT/.lustre/fid"
15434         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15435
15436         echo "listxattr for $MOUNT/.lustre/fid"
15437         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15438
15439         echo "delxattr from $MOUNT/.lustre/fid"
15440         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15441
15442         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15443         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15444                 error "touch invalid fid should fail."
15445
15446         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15447         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15448                 error "touch non-normal fid should fail."
15449
15450         echo "rename $tdir to $MOUNT/.lustre/fid"
15451         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15452                 error "rename to $MOUNT/.lustre/fid should fail."
15453
15454         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15455         then            # LU-3547
15456                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15457                 local new_obf_mode=777
15458
15459                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15460                 chmod $new_obf_mode $DIR/.lustre/fid ||
15461                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15462
15463                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15464                 [ $obf_mode -eq $new_obf_mode ] ||
15465                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15466
15467                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15468                 chmod $old_obf_mode $DIR/.lustre/fid ||
15469                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15470         fi
15471
15472         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15473         fid=$($LFS path2fid $test_dir/$tfile-2)
15474
15475         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15476         then # LU-5424
15477                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15478                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15479                         error "create lov data thru .lustre failed"
15480         fi
15481         echo "cp /etc/passwd $test_dir/$tfile-2"
15482         cp /etc/passwd $test_dir/$tfile-2 ||
15483                 error "copy to $test_dir/$tfile-2 failed."
15484         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15485         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15486                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15487
15488         rm -rf $test_dir/tfile.lnk
15489         rm -rf $test_dir/$tfile-2
15490 }
15491
15492 test_154A() {
15493         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15494                 skip "Need MDS version at least 2.4.1"
15495
15496         local tf=$DIR/$tfile
15497         touch $tf
15498
15499         local fid=$($LFS path2fid $tf)
15500         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15501
15502         # check that we get the same pathname back
15503         local rootpath
15504         local found
15505         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15506                 echo "$rootpath $fid"
15507                 found=$($LFS fid2path $rootpath "$fid")
15508                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15509                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15510         done
15511
15512         # check wrong root path format
15513         rootpath=$MOUNT"_wrong"
15514         found=$($LFS fid2path $rootpath "$fid")
15515         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15516 }
15517 run_test 154A "lfs path2fid and fid2path basic checks"
15518
15519 test_154B() {
15520         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15521                 skip "Need MDS version at least 2.4.1"
15522
15523         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15524         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15525         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15526         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15527
15528         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15529         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15530
15531         # check that we get the same pathname
15532         echo "PFID: $PFID, name: $name"
15533         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15534         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15535         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15536                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15537
15538         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15539 }
15540 run_test 154B "verify the ll_decode_linkea tool"
15541
15542 test_154a() {
15543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15544         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15545         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15546                 skip "Need MDS version at least 2.2.51"
15547         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15548
15549         cp /etc/hosts $DIR/$tfile
15550
15551         fid=$($LFS path2fid $DIR/$tfile)
15552         rc=$?
15553         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15554
15555         dot_lustre_fid_permission_check "$fid" $DIR ||
15556                 error "dot lustre permission check $fid failed"
15557
15558         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15559
15560         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15561
15562         touch $MOUNT/.lustre/file &&
15563                 error "creation is not allowed under .lustre"
15564
15565         mkdir $MOUNT/.lustre/dir &&
15566                 error "mkdir is not allowed under .lustre"
15567
15568         rm -rf $DIR/$tfile
15569 }
15570 run_test 154a "Open-by-FID"
15571
15572 test_154b() {
15573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15574         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15576         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15577                 skip "Need MDS version at least 2.2.51"
15578
15579         local remote_dir=$DIR/$tdir/remote_dir
15580         local MDTIDX=1
15581         local rc=0
15582
15583         mkdir -p $DIR/$tdir
15584         $LFS mkdir -i $MDTIDX $remote_dir ||
15585                 error "create remote directory failed"
15586
15587         cp /etc/hosts $remote_dir/$tfile
15588
15589         fid=$($LFS path2fid $remote_dir/$tfile)
15590         rc=$?
15591         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15592
15593         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15594                 error "dot lustre permission check $fid failed"
15595         rm -rf $DIR/$tdir
15596 }
15597 run_test 154b "Open-by-FID for remote directory"
15598
15599 test_154c() {
15600         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15601                 skip "Need MDS version at least 2.4.1"
15602
15603         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15604         local FID1=$($LFS path2fid $DIR/$tfile.1)
15605         local FID2=$($LFS path2fid $DIR/$tfile.2)
15606         local FID3=$($LFS path2fid $DIR/$tfile.3)
15607
15608         local N=1
15609         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15610                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15611                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15612                 local want=FID$N
15613                 [ "$FID" = "${!want}" ] ||
15614                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15615                 N=$((N + 1))
15616         done
15617
15618         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15619         do
15620                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15621                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15622                 N=$((N + 1))
15623         done
15624 }
15625 run_test 154c "lfs path2fid and fid2path multiple arguments"
15626
15627 test_154d() {
15628         remote_mds_nodsh && skip "remote MDS with nodsh"
15629         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15630                 skip "Need MDS version at least 2.5.53"
15631
15632         if remote_mds; then
15633                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15634         else
15635                 nid="0@lo"
15636         fi
15637         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15638         local fd
15639         local cmd
15640
15641         rm -f $DIR/$tfile
15642         touch $DIR/$tfile
15643
15644         local fid=$($LFS path2fid $DIR/$tfile)
15645         # Open the file
15646         fd=$(free_fd)
15647         cmd="exec $fd<$DIR/$tfile"
15648         eval $cmd
15649         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15650         echo "$fid_list" | grep "$fid"
15651         rc=$?
15652
15653         cmd="exec $fd>/dev/null"
15654         eval $cmd
15655         if [ $rc -ne 0 ]; then
15656                 error "FID $fid not found in open files list $fid_list"
15657         fi
15658 }
15659 run_test 154d "Verify open file fid"
15660
15661 test_154e()
15662 {
15663         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15664                 skip "Need MDS version at least 2.6.50"
15665
15666         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15667                 error ".lustre returned by readdir"
15668         fi
15669 }
15670 run_test 154e ".lustre is not returned by readdir"
15671
15672 test_154f() {
15673         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15674
15675         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15676         mkdir_on_mdt0 $DIR/$tdir
15677         # test dirs inherit from its stripe
15678         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15679         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15680         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15681         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15682         touch $DIR/f
15683
15684         # get fid of parents
15685         local FID0=$($LFS path2fid $DIR/$tdir)
15686         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15687         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15688         local FID3=$($LFS path2fid $DIR)
15689
15690         # check that path2fid --parents returns expected <parent_fid>/name
15691         # 1) test for a directory (single parent)
15692         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15693         [ "$parent" == "$FID0/foo1" ] ||
15694                 error "expected parent: $FID0/foo1, got: $parent"
15695
15696         # 2) test for a file with nlink > 1 (multiple parents)
15697         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15698         echo "$parent" | grep -F "$FID1/$tfile" ||
15699                 error "$FID1/$tfile not returned in parent list"
15700         echo "$parent" | grep -F "$FID2/link" ||
15701                 error "$FID2/link not returned in parent list"
15702
15703         # 3) get parent by fid
15704         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15705         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15706         echo "$parent" | grep -F "$FID1/$tfile" ||
15707                 error "$FID1/$tfile not returned in parent list (by fid)"
15708         echo "$parent" | grep -F "$FID2/link" ||
15709                 error "$FID2/link not returned in parent list (by fid)"
15710
15711         # 4) test for entry in root directory
15712         parent=$($LFS path2fid --parents $DIR/f)
15713         echo "$parent" | grep -F "$FID3/f" ||
15714                 error "$FID3/f not returned in parent list"
15715
15716         # 5) test it on root directory
15717         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15718                 error "$MOUNT should not have parents"
15719
15720         # enable xattr caching and check that linkea is correctly updated
15721         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15722         save_lustre_params client "llite.*.xattr_cache" > $save
15723         lctl set_param llite.*.xattr_cache 1
15724
15725         # 6.1) linkea update on rename
15726         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15727
15728         # get parents by fid
15729         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15730         # foo1 should no longer be returned in parent list
15731         echo "$parent" | grep -F "$FID1" &&
15732                 error "$FID1 should no longer be in parent list"
15733         # the new path should appear
15734         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15735                 error "$FID2/$tfile.moved is not in parent list"
15736
15737         # 6.2) linkea update on unlink
15738         rm -f $DIR/$tdir/foo2/link
15739         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15740         # foo2/link should no longer be returned in parent list
15741         echo "$parent" | grep -F "$FID2/link" &&
15742                 error "$FID2/link should no longer be in parent list"
15743         true
15744
15745         rm -f $DIR/f
15746         restore_lustre_params < $save
15747         rm -f $save
15748 }
15749 run_test 154f "get parent fids by reading link ea"
15750
15751 test_154g()
15752 {
15753         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15754         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15755            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15756                 skip "Need MDS version at least 2.6.92"
15757
15758         mkdir_on_mdt0 $DIR/$tdir
15759         llapi_fid_test -d $DIR/$tdir
15760 }
15761 run_test 154g "various llapi FID tests"
15762
15763 test_155_small_load() {
15764     local temp=$TMP/$tfile
15765     local file=$DIR/$tfile
15766
15767     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15768         error "dd of=$temp bs=6096 count=1 failed"
15769     cp $temp $file
15770     cancel_lru_locks $OSC
15771     cmp $temp $file || error "$temp $file differ"
15772
15773     $TRUNCATE $temp 6000
15774     $TRUNCATE $file 6000
15775     cmp $temp $file || error "$temp $file differ (truncate1)"
15776
15777     echo "12345" >>$temp
15778     echo "12345" >>$file
15779     cmp $temp $file || error "$temp $file differ (append1)"
15780
15781     echo "12345" >>$temp
15782     echo "12345" >>$file
15783     cmp $temp $file || error "$temp $file differ (append2)"
15784
15785     rm -f $temp $file
15786     true
15787 }
15788
15789 test_155_big_load() {
15790         remote_ost_nodsh && skip "remote OST with nodsh"
15791
15792         local temp=$TMP/$tfile
15793         local file=$DIR/$tfile
15794
15795         free_min_max
15796         local cache_size=$(do_facet ost$((MAXI+1)) \
15797                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15798
15799         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15800         # pre-set value
15801         if [ -z "$cache_size" ]; then
15802                 cache_size=256
15803         fi
15804         local large_file_size=$((cache_size * 2))
15805
15806         echo "OSS cache size: $cache_size KB"
15807         echo "Large file size: $large_file_size KB"
15808
15809         [ $MAXV -le $large_file_size ] &&
15810                 skip_env "max available OST size needs > $large_file_size KB"
15811
15812         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15813
15814         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15815                 error "dd of=$temp bs=$large_file_size count=1k failed"
15816         cp $temp $file
15817         ls -lh $temp $file
15818         cancel_lru_locks osc
15819         cmp $temp $file || error "$temp $file differ"
15820
15821         rm -f $temp $file
15822         true
15823 }
15824
15825 save_writethrough() {
15826         local facets=$(get_facets OST)
15827
15828         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15829 }
15830
15831 test_155a() {
15832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15833
15834         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15835
15836         save_writethrough $p
15837
15838         set_cache read on
15839         set_cache writethrough on
15840         test_155_small_load
15841         restore_lustre_params < $p
15842         rm -f $p
15843 }
15844 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15845
15846 test_155b() {
15847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15848
15849         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15850
15851         save_writethrough $p
15852
15853         set_cache read on
15854         set_cache writethrough off
15855         test_155_small_load
15856         restore_lustre_params < $p
15857         rm -f $p
15858 }
15859 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15860
15861 test_155c() {
15862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15863
15864         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15865
15866         save_writethrough $p
15867
15868         set_cache read off
15869         set_cache writethrough on
15870         test_155_small_load
15871         restore_lustre_params < $p
15872         rm -f $p
15873 }
15874 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15875
15876 test_155d() {
15877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15878
15879         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15880
15881         save_writethrough $p
15882
15883         set_cache read off
15884         set_cache writethrough off
15885         test_155_small_load
15886         restore_lustre_params < $p
15887         rm -f $p
15888 }
15889 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15890
15891 test_155e() {
15892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15893
15894         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15895
15896         save_writethrough $p
15897
15898         set_cache read on
15899         set_cache writethrough on
15900         test_155_big_load
15901         restore_lustre_params < $p
15902         rm -f $p
15903 }
15904 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15905
15906 test_155f() {
15907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15908
15909         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15910
15911         save_writethrough $p
15912
15913         set_cache read on
15914         set_cache writethrough off
15915         test_155_big_load
15916         restore_lustre_params < $p
15917         rm -f $p
15918 }
15919 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15920
15921 test_155g() {
15922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15923
15924         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15925
15926         save_writethrough $p
15927
15928         set_cache read off
15929         set_cache writethrough on
15930         test_155_big_load
15931         restore_lustre_params < $p
15932         rm -f $p
15933 }
15934 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15935
15936 test_155h() {
15937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15938
15939         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15940
15941         save_writethrough $p
15942
15943         set_cache read off
15944         set_cache writethrough off
15945         test_155_big_load
15946         restore_lustre_params < $p
15947         rm -f $p
15948 }
15949 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15950
15951 test_156() {
15952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15953         remote_ost_nodsh && skip "remote OST with nodsh"
15954         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15955                 skip "stats not implemented on old servers"
15956         [ "$ost1_FSTYPE" = "zfs" ] &&
15957                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15958
15959         local CPAGES=3
15960         local BEFORE
15961         local AFTER
15962         local file="$DIR/$tfile"
15963         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15964
15965         save_writethrough $p
15966         roc_hit_init
15967
15968         log "Turn on read and write cache"
15969         set_cache read on
15970         set_cache writethrough on
15971
15972         log "Write data and read it back."
15973         log "Read should be satisfied from the cache."
15974         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15975         BEFORE=$(roc_hit)
15976         cancel_lru_locks osc
15977         cat $file >/dev/null
15978         AFTER=$(roc_hit)
15979         if ! let "AFTER - BEFORE == CPAGES"; then
15980                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15981         else
15982                 log "cache hits: before: $BEFORE, after: $AFTER"
15983         fi
15984
15985         log "Read again; it should be satisfied from the cache."
15986         BEFORE=$AFTER
15987         cancel_lru_locks osc
15988         cat $file >/dev/null
15989         AFTER=$(roc_hit)
15990         if ! let "AFTER - BEFORE == CPAGES"; then
15991                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15992         else
15993                 log "cache hits:: before: $BEFORE, after: $AFTER"
15994         fi
15995
15996         log "Turn off the read cache and turn on the write cache"
15997         set_cache read off
15998         set_cache writethrough on
15999
16000         log "Read again; it should be satisfied from the cache."
16001         BEFORE=$(roc_hit)
16002         cancel_lru_locks osc
16003         cat $file >/dev/null
16004         AFTER=$(roc_hit)
16005         if ! let "AFTER - BEFORE == CPAGES"; then
16006                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16007         else
16008                 log "cache hits:: before: $BEFORE, after: $AFTER"
16009         fi
16010
16011         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16012                 # > 2.12.56 uses pagecache if cached
16013                 log "Read again; it should not be satisfied from the cache."
16014                 BEFORE=$AFTER
16015                 cancel_lru_locks osc
16016                 cat $file >/dev/null
16017                 AFTER=$(roc_hit)
16018                 if ! let "AFTER - BEFORE == 0"; then
16019                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16020                 else
16021                         log "cache hits:: before: $BEFORE, after: $AFTER"
16022                 fi
16023         fi
16024
16025         log "Write data and read it back."
16026         log "Read should be satisfied from the cache."
16027         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16028         BEFORE=$(roc_hit)
16029         cancel_lru_locks osc
16030         cat $file >/dev/null
16031         AFTER=$(roc_hit)
16032         if ! let "AFTER - BEFORE == CPAGES"; then
16033                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16034         else
16035                 log "cache hits:: before: $BEFORE, after: $AFTER"
16036         fi
16037
16038         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16039                 # > 2.12.56 uses pagecache if cached
16040                 log "Read again; it should not be satisfied from the cache."
16041                 BEFORE=$AFTER
16042                 cancel_lru_locks osc
16043                 cat $file >/dev/null
16044                 AFTER=$(roc_hit)
16045                 if ! let "AFTER - BEFORE == 0"; then
16046                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16047                 else
16048                         log "cache hits:: before: $BEFORE, after: $AFTER"
16049                 fi
16050         fi
16051
16052         log "Turn off read and write cache"
16053         set_cache read off
16054         set_cache writethrough off
16055
16056         log "Write data and read it back"
16057         log "It should not be satisfied from the cache."
16058         rm -f $file
16059         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16060         cancel_lru_locks osc
16061         BEFORE=$(roc_hit)
16062         cat $file >/dev/null
16063         AFTER=$(roc_hit)
16064         if ! let "AFTER - BEFORE == 0"; then
16065                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16066         else
16067                 log "cache hits:: before: $BEFORE, after: $AFTER"
16068         fi
16069
16070         log "Turn on the read cache and turn off the write cache"
16071         set_cache read on
16072         set_cache writethrough off
16073
16074         log "Write data and read it back"
16075         log "It should not be satisfied from the cache."
16076         rm -f $file
16077         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16078         BEFORE=$(roc_hit)
16079         cancel_lru_locks osc
16080         cat $file >/dev/null
16081         AFTER=$(roc_hit)
16082         if ! let "AFTER - BEFORE == 0"; then
16083                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16084         else
16085                 log "cache hits:: before: $BEFORE, after: $AFTER"
16086         fi
16087
16088         log "Read again; it should be satisfied from the cache."
16089         BEFORE=$(roc_hit)
16090         cancel_lru_locks osc
16091         cat $file >/dev/null
16092         AFTER=$(roc_hit)
16093         if ! let "AFTER - BEFORE == CPAGES"; then
16094                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16095         else
16096                 log "cache hits:: before: $BEFORE, after: $AFTER"
16097         fi
16098
16099         restore_lustre_params < $p
16100         rm -f $p $file
16101 }
16102 run_test 156 "Verification of tunables"
16103
16104 test_160a() {
16105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16106         remote_mds_nodsh && skip "remote MDS with nodsh"
16107         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16108                 skip "Need MDS version at least 2.2.0"
16109
16110         changelog_register || error "changelog_register failed"
16111         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16112         changelog_users $SINGLEMDS | grep -q $cl_user ||
16113                 error "User $cl_user not found in changelog_users"
16114
16115         mkdir_on_mdt0 $DIR/$tdir
16116
16117         # change something
16118         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16119         changelog_clear 0 || error "changelog_clear failed"
16120         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16121         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16122         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16123         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16124         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16125         rm $DIR/$tdir/pics/desktop.jpg
16126
16127         echo "verifying changelog mask"
16128         changelog_chmask "-MKDIR"
16129         changelog_chmask "-CLOSE"
16130
16131         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16132         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16133
16134         changelog_chmask "+MKDIR"
16135         changelog_chmask "+CLOSE"
16136
16137         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16138         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16139
16140         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16141         CLOSES=$(changelog_dump | grep -c "CLOSE")
16142         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16143         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16144
16145         # verify contents
16146         echo "verifying target fid"
16147         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16148         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16149         [ "$fidc" == "$fidf" ] ||
16150                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16151         echo "verifying parent fid"
16152         # The FID returned from the Changelog may be the directory shard on
16153         # a different MDT, and not the FID returned by path2fid on the parent.
16154         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16155         # since this is what will matter when recreating this file in the tree.
16156         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16157         local pathp=$($LFS fid2path $MOUNT "$fidp")
16158         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16159                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16160
16161         echo "getting records for $cl_user"
16162         changelog_users $SINGLEMDS
16163         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16164         local nclr=3
16165         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16166                 error "changelog_clear failed"
16167         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16168         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16169         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16170                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16171
16172         local min0_rec=$(changelog_users $SINGLEMDS |
16173                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16174         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16175                           awk '{ print $1; exit; }')
16176
16177         changelog_dump | tail -n 5
16178         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16179         [ $first_rec == $((min0_rec + 1)) ] ||
16180                 error "first index should be $min0_rec + 1 not $first_rec"
16181
16182         # LU-3446 changelog index reset on MDT restart
16183         local cur_rec1=$(changelog_users $SINGLEMDS |
16184                          awk '/^current.index:/ { print $NF }')
16185         changelog_clear 0 ||
16186                 error "clear all changelog records for $cl_user failed"
16187         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16188         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16189                 error "Fail to start $SINGLEMDS"
16190         local cur_rec2=$(changelog_users $SINGLEMDS |
16191                          awk '/^current.index:/ { print $NF }')
16192         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16193         [ $cur_rec1 == $cur_rec2 ] ||
16194                 error "current index should be $cur_rec1 not $cur_rec2"
16195
16196         echo "verifying users from this test are deregistered"
16197         changelog_deregister || error "changelog_deregister failed"
16198         changelog_users $SINGLEMDS | grep -q $cl_user &&
16199                 error "User '$cl_user' still in changelog_users"
16200
16201         # lctl get_param -n mdd.*.changelog_users
16202         # current_index: 144
16203         # ID    index (idle seconds)
16204         # cl3   144   (2) mask=<list>
16205         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16206                 # this is the normal case where all users were deregistered
16207                 # make sure no new records are added when no users are present
16208                 local last_rec1=$(changelog_users $SINGLEMDS |
16209                                   awk '/^current.index:/ { print $NF }')
16210                 touch $DIR/$tdir/chloe
16211                 local last_rec2=$(changelog_users $SINGLEMDS |
16212                                   awk '/^current.index:/ { print $NF }')
16213                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16214                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16215         else
16216                 # any changelog users must be leftovers from a previous test
16217                 changelog_users $SINGLEMDS
16218                 echo "other changelog users; can't verify off"
16219         fi
16220 }
16221 run_test 160a "changelog sanity"
16222
16223 test_160b() { # LU-3587
16224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16225         remote_mds_nodsh && skip "remote MDS with nodsh"
16226         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16227                 skip "Need MDS version at least 2.2.0"
16228
16229         changelog_register || error "changelog_register failed"
16230         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16231         changelog_users $SINGLEMDS | grep -q $cl_user ||
16232                 error "User '$cl_user' not found in changelog_users"
16233
16234         local longname1=$(str_repeat a 255)
16235         local longname2=$(str_repeat b 255)
16236
16237         cd $DIR
16238         echo "creating very long named file"
16239         touch $longname1 || error "create of '$longname1' failed"
16240         echo "renaming very long named file"
16241         mv $longname1 $longname2
16242
16243         changelog_dump | grep RENME | tail -n 5
16244         rm -f $longname2
16245 }
16246 run_test 160b "Verify that very long rename doesn't crash in changelog"
16247
16248 test_160c() {
16249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16250         remote_mds_nodsh && skip "remote MDS with nodsh"
16251
16252         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16253                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16254                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16255                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16256
16257         local rc=0
16258
16259         # Registration step
16260         changelog_register || error "changelog_register failed"
16261
16262         rm -rf $DIR/$tdir
16263         mkdir -p $DIR/$tdir
16264         $MCREATE $DIR/$tdir/foo_160c
16265         changelog_chmask "-TRUNC"
16266         $TRUNCATE $DIR/$tdir/foo_160c 200
16267         changelog_chmask "+TRUNC"
16268         $TRUNCATE $DIR/$tdir/foo_160c 199
16269         changelog_dump | tail -n 5
16270         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16271         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16272 }
16273 run_test 160c "verify that changelog log catch the truncate event"
16274
16275 test_160d() {
16276         remote_mds_nodsh && skip "remote MDS with nodsh"
16277         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16279         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16280                 skip "Need MDS version at least 2.7.60"
16281
16282         # Registration step
16283         changelog_register || error "changelog_register failed"
16284
16285         mkdir -p $DIR/$tdir/migrate_dir
16286         changelog_clear 0 || error "changelog_clear failed"
16287
16288         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16289         changelog_dump | tail -n 5
16290         local migrates=$(changelog_dump | grep -c "MIGRT")
16291         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16292 }
16293 run_test 160d "verify that changelog log catch the migrate event"
16294
16295 test_160e() {
16296         remote_mds_nodsh && skip "remote MDS with nodsh"
16297
16298         # Create a user
16299         changelog_register || error "changelog_register failed"
16300
16301         local MDT0=$(facet_svc $SINGLEMDS)
16302         local rc
16303
16304         # No user (expect fail)
16305         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16306         rc=$?
16307         if [ $rc -eq 0 ]; then
16308                 error "Should fail without user"
16309         elif [ $rc -ne 4 ]; then
16310                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16311         fi
16312
16313         # Delete a future user (expect fail)
16314         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16315         rc=$?
16316         if [ $rc -eq 0 ]; then
16317                 error "Deleted non-existant user cl77"
16318         elif [ $rc -ne 2 ]; then
16319                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16320         fi
16321
16322         # Clear to a bad index (1 billion should be safe)
16323         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16324         rc=$?
16325
16326         if [ $rc -eq 0 ]; then
16327                 error "Successfully cleared to invalid CL index"
16328         elif [ $rc -ne 22 ]; then
16329                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16330         fi
16331 }
16332 run_test 160e "changelog negative testing (should return errors)"
16333
16334 test_160f() {
16335         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16336         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16337                 skip "Need MDS version at least 2.10.56"
16338
16339         local mdts=$(comma_list $(mdts_nodes))
16340
16341         # Create a user
16342         changelog_register || error "first changelog_register failed"
16343         changelog_register || error "second changelog_register failed"
16344         local cl_users
16345         declare -A cl_user1
16346         declare -A cl_user2
16347         local user_rec1
16348         local user_rec2
16349         local i
16350
16351         # generate some changelog records to accumulate on each MDT
16352         # use all_char because created files should be evenly distributed
16353         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16354                 error "test_mkdir $tdir failed"
16355         log "$(date +%s): creating first files"
16356         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16357                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16358                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16359         done
16360
16361         # check changelogs have been generated
16362         local start=$SECONDS
16363         local idle_time=$((MDSCOUNT * 5 + 5))
16364         local nbcl=$(changelog_dump | wc -l)
16365         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16366
16367         for param in "changelog_max_idle_time=$idle_time" \
16368                      "changelog_gc=1" \
16369                      "changelog_min_gc_interval=2" \
16370                      "changelog_min_free_cat_entries=3"; do
16371                 local MDT0=$(facet_svc $SINGLEMDS)
16372                 local var="${param%=*}"
16373                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16374
16375                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16376                 do_nodes $mdts $LCTL set_param mdd.*.$param
16377         done
16378
16379         # force cl_user2 to be idle (1st part), but also cancel the
16380         # cl_user1 records so that it is not evicted later in the test.
16381         local sleep1=$((idle_time / 2))
16382         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16383         sleep $sleep1
16384
16385         # simulate changelog catalog almost full
16386         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16387         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16388
16389         for i in $(seq $MDSCOUNT); do
16390                 cl_users=(${CL_USERS[mds$i]})
16391                 cl_user1[mds$i]="${cl_users[0]}"
16392                 cl_user2[mds$i]="${cl_users[1]}"
16393
16394                 [ -n "${cl_user1[mds$i]}" ] ||
16395                         error "mds$i: no user registered"
16396                 [ -n "${cl_user2[mds$i]}" ] ||
16397                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16398
16399                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16400                 [ -n "$user_rec1" ] ||
16401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16402                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16403                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16404                 [ -n "$user_rec2" ] ||
16405                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16406                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16407                      "$user_rec1 + 2 == $user_rec2"
16408                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16409                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16410                               "$user_rec1 + 2, but is $user_rec2"
16411                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16412                 [ -n "$user_rec2" ] ||
16413                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16414                 [ $user_rec1 == $user_rec2 ] ||
16415                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16416                               "$user_rec1, but is $user_rec2"
16417         done
16418
16419         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16420         local sleep2=$((idle_time - (SECONDS - start) + 1))
16421         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16422         sleep $sleep2
16423
16424         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16425         # cl_user1 should be OK because it recently processed records.
16426         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16427         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16428                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16429                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16430         done
16431
16432         # ensure gc thread is done
16433         for i in $(mdts_nodes); do
16434                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16435                         error "$i: GC-thread not done"
16436         done
16437
16438         local first_rec
16439         for (( i = 1; i <= MDSCOUNT; i++ )); do
16440                 # check cl_user1 still registered
16441                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16442                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16443                 # check cl_user2 unregistered
16444                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16445                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16446
16447                 # check changelogs are present and starting at $user_rec1 + 1
16448                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16449                 [ -n "$user_rec1" ] ||
16450                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16451                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16452                             awk '{ print $1; exit; }')
16453
16454                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16455                 [ $((user_rec1 + 1)) == $first_rec ] ||
16456                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16457         done
16458 }
16459 run_test 160f "changelog garbage collect (timestamped users)"
16460
16461 test_160g() {
16462         remote_mds_nodsh && skip "remote MDS with nodsh"
16463         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16464                 skip "Need MDS version at least 2.14.55"
16465
16466         local mdts=$(comma_list $(mdts_nodes))
16467
16468         # Create a user
16469         changelog_register || error "first changelog_register failed"
16470         changelog_register || error "second changelog_register failed"
16471         local cl_users
16472         declare -A cl_user1
16473         declare -A cl_user2
16474         local user_rec1
16475         local user_rec2
16476         local i
16477
16478         # generate some changelog records to accumulate on each MDT
16479         # use all_char because created files should be evenly distributed
16480         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16481                 error "test_mkdir $tdir failed"
16482         for ((i = 0; i < MDSCOUNT; i++)); do
16483                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16484                         error "create $DIR/$tdir/d$i.1 failed"
16485         done
16486
16487         # check changelogs have been generated
16488         local nbcl=$(changelog_dump | wc -l)
16489         (( $nbcl > 0 )) || error "no changelogs found"
16490
16491         # reduce the max_idle_indexes value to make sure we exceed it
16492         for param in "changelog_max_idle_indexes=2" \
16493                      "changelog_gc=1" \
16494                      "changelog_min_gc_interval=2"; do
16495                 local MDT0=$(facet_svc $SINGLEMDS)
16496                 local var="${param%=*}"
16497                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16498
16499                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16500                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16501                         error "unable to set mdd.*.$param"
16502         done
16503
16504         local start=$SECONDS
16505         for i in $(seq $MDSCOUNT); do
16506                 cl_users=(${CL_USERS[mds$i]})
16507                 cl_user1[mds$i]="${cl_users[0]}"
16508                 cl_user2[mds$i]="${cl_users[1]}"
16509
16510                 [ -n "${cl_user1[mds$i]}" ] ||
16511                         error "mds$i: user1 is not registered"
16512                 [ -n "${cl_user2[mds$i]}" ] ||
16513                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16514
16515                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16516                 [ -n "$user_rec1" ] ||
16517                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16518                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16519                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16520                 [ -n "$user_rec2" ] ||
16521                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16522                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16523                      "$user_rec1 + 2 == $user_rec2"
16524                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16525                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16526                               "expected $user_rec1 + 2, but is $user_rec2"
16527                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16528                 [ -n "$user_rec2" ] ||
16529                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16530                 [ $user_rec1 == $user_rec2 ] ||
16531                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16532                               "expected $user_rec1, but is $user_rec2"
16533         done
16534
16535         # ensure we are past the previous changelog_min_gc_interval set above
16536         local sleep2=$((start + 2 - SECONDS))
16537         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16538         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16539         # cl_user1 should be OK because it recently processed records.
16540         for ((i = 0; i < MDSCOUNT; i++)); do
16541                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16542                         error "create $DIR/$tdir/d$i.3 failed"
16543         done
16544
16545         # ensure gc thread is done
16546         for i in $(mdts_nodes); do
16547                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16548                         error "$i: GC-thread not done"
16549         done
16550
16551         local first_rec
16552         for (( i = 1; i <= MDSCOUNT; i++ )); do
16553                 # check cl_user1 still registered
16554                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16555                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16556                 # check cl_user2 unregistered
16557                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16558                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16559
16560                 # check changelogs are present and starting at $user_rec1 + 1
16561                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16562                 [ -n "$user_rec1" ] ||
16563                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16564                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16565                             awk '{ print $1; exit; }')
16566
16567                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16568                 [ $((user_rec1 + 1)) == $first_rec ] ||
16569                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16570         done
16571 }
16572 run_test 160g "changelog garbage collect on idle records"
16573
16574 test_160h() {
16575         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16576         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16577                 skip "Need MDS version at least 2.10.56"
16578
16579         local mdts=$(comma_list $(mdts_nodes))
16580
16581         # Create a user
16582         changelog_register || error "first changelog_register failed"
16583         changelog_register || error "second changelog_register failed"
16584         local cl_users
16585         declare -A cl_user1
16586         declare -A cl_user2
16587         local user_rec1
16588         local user_rec2
16589         local i
16590
16591         # generate some changelog records to accumulate on each MDT
16592         # use all_char because created files should be evenly distributed
16593         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16594                 error "test_mkdir $tdir failed"
16595         for ((i = 0; i < MDSCOUNT; i++)); do
16596                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16597                         error "create $DIR/$tdir/d$i.1 failed"
16598         done
16599
16600         # check changelogs have been generated
16601         local nbcl=$(changelog_dump | wc -l)
16602         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16603
16604         for param in "changelog_max_idle_time=10" \
16605                      "changelog_gc=1" \
16606                      "changelog_min_gc_interval=2"; do
16607                 local MDT0=$(facet_svc $SINGLEMDS)
16608                 local var="${param%=*}"
16609                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16610
16611                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16612                 do_nodes $mdts $LCTL set_param mdd.*.$param
16613         done
16614
16615         # force cl_user2 to be idle (1st part)
16616         sleep 9
16617
16618         for i in $(seq $MDSCOUNT); do
16619                 cl_users=(${CL_USERS[mds$i]})
16620                 cl_user1[mds$i]="${cl_users[0]}"
16621                 cl_user2[mds$i]="${cl_users[1]}"
16622
16623                 [ -n "${cl_user1[mds$i]}" ] ||
16624                         error "mds$i: no user registered"
16625                 [ -n "${cl_user2[mds$i]}" ] ||
16626                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16627
16628                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16629                 [ -n "$user_rec1" ] ||
16630                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16631                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16632                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16633                 [ -n "$user_rec2" ] ||
16634                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16635                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16636                      "$user_rec1 + 2 == $user_rec2"
16637                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16638                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16639                               "$user_rec1 + 2, but is $user_rec2"
16640                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16641                 [ -n "$user_rec2" ] ||
16642                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16643                 [ $user_rec1 == $user_rec2 ] ||
16644                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16645                               "$user_rec1, but is $user_rec2"
16646         done
16647
16648         # force cl_user2 to be idle (2nd part) and to reach
16649         # changelog_max_idle_time
16650         sleep 2
16651
16652         # force each GC-thread start and block then
16653         # one per MDT/MDD, set fail_val accordingly
16654         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16655         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16656
16657         # generate more changelogs to trigger fail_loc
16658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16659                 error "create $DIR/$tdir/${tfile}bis failed"
16660
16661         # stop MDT to stop GC-thread, should be done in back-ground as it will
16662         # block waiting for the thread to be released and exit
16663         declare -A stop_pids
16664         for i in $(seq $MDSCOUNT); do
16665                 stop mds$i &
16666                 stop_pids[mds$i]=$!
16667         done
16668
16669         for i in $(mdts_nodes); do
16670                 local facet
16671                 local nb=0
16672                 local facets=$(facets_up_on_host $i)
16673
16674                 for facet in ${facets//,/ }; do
16675                         if [[ $facet == mds* ]]; then
16676                                 nb=$((nb + 1))
16677                         fi
16678                 done
16679                 # ensure each MDS's gc threads are still present and all in "R"
16680                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16681                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16682                         error "$i: expected $nb GC-thread"
16683                 wait_update $i \
16684                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16685                         "R" 20 ||
16686                         error "$i: GC-thread not found in R-state"
16687                 # check umounts of each MDT on MDS have reached kthread_stop()
16688                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16689                         error "$i: expected $nb umount"
16690                 wait_update $i \
16691                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16692                         error "$i: umount not found in D-state"
16693         done
16694
16695         # release all GC-threads
16696         do_nodes $mdts $LCTL set_param fail_loc=0
16697
16698         # wait for MDT stop to complete
16699         for i in $(seq $MDSCOUNT); do
16700                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16701         done
16702
16703         # XXX
16704         # may try to check if any orphan changelog records are present
16705         # via ldiskfs/zfs and llog_reader...
16706
16707         # re-start/mount MDTs
16708         for i in $(seq $MDSCOUNT); do
16709                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16710                         error "Fail to start mds$i"
16711         done
16712
16713         local first_rec
16714         for i in $(seq $MDSCOUNT); do
16715                 # check cl_user1 still registered
16716                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16717                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16718                 # check cl_user2 unregistered
16719                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16720                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16721
16722                 # check changelogs are present and starting at $user_rec1 + 1
16723                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16724                 [ -n "$user_rec1" ] ||
16725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16726                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16727                             awk '{ print $1; exit; }')
16728
16729                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16730                 [ $((user_rec1 + 1)) == $first_rec ] ||
16731                         error "mds$i: first index should be $user_rec1 + 1, " \
16732                               "but is $first_rec"
16733         done
16734 }
16735 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16736               "during mount"
16737
16738 test_160i() {
16739
16740         local mdts=$(comma_list $(mdts_nodes))
16741
16742         changelog_register || error "first changelog_register failed"
16743
16744         # generate some changelog records to accumulate on each MDT
16745         # use all_char because created files should be evenly distributed
16746         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16747                 error "test_mkdir $tdir failed"
16748         for ((i = 0; i < MDSCOUNT; i++)); do
16749                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16750                         error "create $DIR/$tdir/d$i.1 failed"
16751         done
16752
16753         # check changelogs have been generated
16754         local nbcl=$(changelog_dump | wc -l)
16755         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16756
16757         # simulate race between register and unregister
16758         # XXX as fail_loc is set per-MDS, with DNE configs the race
16759         # simulation will only occur for one MDT per MDS and for the
16760         # others the normal race scenario will take place
16761         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16762         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16763         do_nodes $mdts $LCTL set_param fail_val=1
16764
16765         # unregister 1st user
16766         changelog_deregister &
16767         local pid1=$!
16768         # wait some time for deregister work to reach race rdv
16769         sleep 2
16770         # register 2nd user
16771         changelog_register || error "2nd user register failed"
16772
16773         wait $pid1 || error "1st user deregister failed"
16774
16775         local i
16776         local last_rec
16777         declare -A LAST_REC
16778         for i in $(seq $MDSCOUNT); do
16779                 if changelog_users mds$i | grep "^cl"; then
16780                         # make sure new records are added with one user present
16781                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16782                                           awk '/^current.index:/ { print $NF }')
16783                 else
16784                         error "mds$i has no user registered"
16785                 fi
16786         done
16787
16788         # generate more changelog records to accumulate on each MDT
16789         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16790                 error "create $DIR/$tdir/${tfile}bis failed"
16791
16792         for i in $(seq $MDSCOUNT); do
16793                 last_rec=$(changelog_users $SINGLEMDS |
16794                            awk '/^current.index:/ { print $NF }')
16795                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16796                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16797                         error "changelogs are off on mds$i"
16798         done
16799 }
16800 run_test 160i "changelog user register/unregister race"
16801
16802 test_160j() {
16803         remote_mds_nodsh && skip "remote MDS with nodsh"
16804         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16805                 skip "Need MDS version at least 2.12.56"
16806
16807         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16808         stack_trap "umount $MOUNT2" EXIT
16809
16810         changelog_register || error "first changelog_register failed"
16811         stack_trap "changelog_deregister" EXIT
16812
16813         # generate some changelog
16814         # use all_char because created files should be evenly distributed
16815         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16816                 error "mkdir $tdir failed"
16817         for ((i = 0; i < MDSCOUNT; i++)); do
16818                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16819                         error "create $DIR/$tdir/d$i.1 failed"
16820         done
16821
16822         # open the changelog device
16823         exec 3>/dev/changelog-$FSNAME-MDT0000
16824         stack_trap "exec 3>&-" EXIT
16825         exec 4</dev/changelog-$FSNAME-MDT0000
16826         stack_trap "exec 4<&-" EXIT
16827
16828         # umount the first lustre mount
16829         umount $MOUNT
16830         stack_trap "mount_client $MOUNT" EXIT
16831
16832         # read changelog, which may or may not fail, but should not crash
16833         cat <&4 >/dev/null
16834
16835         # clear changelog
16836         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16837         changelog_users $SINGLEMDS | grep -q $cl_user ||
16838                 error "User $cl_user not found in changelog_users"
16839
16840         printf 'clear:'$cl_user':0' >&3
16841 }
16842 run_test 160j "client can be umounted while its chanangelog is being used"
16843
16844 test_160k() {
16845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16846         remote_mds_nodsh && skip "remote MDS with nodsh"
16847
16848         mkdir -p $DIR/$tdir/1/1
16849
16850         changelog_register || error "changelog_register failed"
16851         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16852
16853         changelog_users $SINGLEMDS | grep -q $cl_user ||
16854                 error "User '$cl_user' not found in changelog_users"
16855 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16856         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16857         rmdir $DIR/$tdir/1/1 & sleep 1
16858         mkdir $DIR/$tdir/2
16859         touch $DIR/$tdir/2/2
16860         rm -rf $DIR/$tdir/2
16861
16862         wait
16863         sleep 4
16864
16865         changelog_dump | grep rmdir || error "rmdir not recorded"
16866 }
16867 run_test 160k "Verify that changelog records are not lost"
16868
16869 # Verifies that a file passed as a parameter has recently had an operation
16870 # performed on it that has generated an MTIME changelog which contains the
16871 # correct parent FID. As files might reside on a different MDT from the
16872 # parent directory in DNE configurations, the FIDs are translated to paths
16873 # before being compared, which should be identical
16874 compare_mtime_changelog() {
16875         local file="${1}"
16876         local mdtidx
16877         local mtime
16878         local cl_fid
16879         local pdir
16880         local dir
16881
16882         mdtidx=$($LFS getstripe --mdt-index $file)
16883         mdtidx=$(printf "%04x" $mdtidx)
16884
16885         # Obtain the parent FID from the MTIME changelog
16886         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16887         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16888
16889         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16890         [ -z "$cl_fid" ] && error "parent FID not present"
16891
16892         # Verify that the path for the parent FID is the same as the path for
16893         # the test directory
16894         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16895
16896         dir=$(dirname $1)
16897
16898         [[ "${pdir%/}" == "$dir" ]] ||
16899                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16900 }
16901
16902 test_160l() {
16903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16904
16905         remote_mds_nodsh && skip "remote MDS with nodsh"
16906         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16907                 skip "Need MDS version at least 2.13.55"
16908
16909         local cl_user
16910
16911         changelog_register || error "changelog_register failed"
16912         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16913
16914         changelog_users $SINGLEMDS | grep -q $cl_user ||
16915                 error "User '$cl_user' not found in changelog_users"
16916
16917         # Clear some types so that MTIME changelogs are generated
16918         changelog_chmask "-CREAT"
16919         changelog_chmask "-CLOSE"
16920
16921         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16922
16923         # Test CL_MTIME during setattr
16924         touch $DIR/$tdir/$tfile
16925         compare_mtime_changelog $DIR/$tdir/$tfile
16926
16927         # Test CL_MTIME during close
16928         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16929         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16930 }
16931 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16932
16933 test_160m() {
16934         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16935         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16936                 skip "Need MDS version at least 2.14.51"
16937         local cl_users
16938         local cl_user1
16939         local cl_user2
16940         local pid1
16941
16942         # Create a user
16943         changelog_register || error "first changelog_register failed"
16944         changelog_register || error "second changelog_register failed"
16945
16946         cl_users=(${CL_USERS[mds1]})
16947         cl_user1="${cl_users[0]}"
16948         cl_user2="${cl_users[1]}"
16949         # generate some changelog records to accumulate on MDT0
16950         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16951         createmany -m $DIR/$tdir/$tfile 50 ||
16952                 error "create $DIR/$tdir/$tfile failed"
16953         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16954         rm -f $DIR/$tdir
16955
16956         # check changelogs have been generated
16957         local nbcl=$(changelog_dump | wc -l)
16958         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16959
16960 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16961         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16962
16963         __changelog_clear mds1 $cl_user1 +10
16964         __changelog_clear mds1 $cl_user2 0 &
16965         pid1=$!
16966         sleep 2
16967         __changelog_clear mds1 $cl_user1 0 ||
16968                 error "fail to cancel record for $cl_user1"
16969         wait $pid1
16970         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16971 }
16972 run_test 160m "Changelog clear race"
16973
16974 test_160n() {
16975         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16976         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16977                 skip "Need MDS version at least 2.14.51"
16978         local cl_users
16979         local cl_user1
16980         local cl_user2
16981         local pid1
16982         local first_rec
16983         local last_rec=0
16984
16985         # Create a user
16986         changelog_register || error "first changelog_register failed"
16987
16988         cl_users=(${CL_USERS[mds1]})
16989         cl_user1="${cl_users[0]}"
16990
16991         # generate some changelog records to accumulate on MDT0
16992         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16993         first_rec=$(changelog_users $SINGLEMDS |
16994                         awk '/^current.index:/ { print $NF }')
16995         while (( last_rec < (( first_rec + 65000)) )); do
16996                 createmany -m $DIR/$tdir/$tfile 10000 ||
16997                         error "create $DIR/$tdir/$tfile failed"
16998
16999                 for i in $(seq 0 10000); do
17000                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17001                                 > /dev/null
17002                 done
17003
17004                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17005                         error "unlinkmany failed unlink"
17006                 last_rec=$(changelog_users $SINGLEMDS |
17007                         awk '/^current.index:/ { print $NF }')
17008                 echo last record $last_rec
17009                 (( last_rec == 0 )) && error "no changelog found"
17010         done
17011
17012 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17013         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17014
17015         __changelog_clear mds1 $cl_user1 0 &
17016         pid1=$!
17017         sleep 2
17018         __changelog_clear mds1 $cl_user1 0 ||
17019                 error "fail to cancel record for $cl_user1"
17020         wait $pid1
17021         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17022 }
17023 run_test 160n "Changelog destroy race"
17024
17025 test_160o() {
17026         local mdt="$(facet_svc $SINGLEMDS)"
17027
17028         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17029         remote_mds_nodsh && skip "remote MDS with nodsh"
17030         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17031                 skip "Need MDS version at least 2.14.52"
17032
17033         changelog_register --user test_160o -m unlnk+close+open ||
17034                 error "changelog_register failed"
17035
17036         do_facet $SINGLEMDS $LCTL --device $mdt \
17037                                 changelog_register -u "Tt3_-#" &&
17038                 error "bad symbols in name should fail"
17039
17040         do_facet $SINGLEMDS $LCTL --device $mdt \
17041                                 changelog_register -u test_160o &&
17042                 error "the same name registration should fail"
17043
17044         do_facet $SINGLEMDS $LCTL --device $mdt \
17045                         changelog_register -u test_160toolongname &&
17046                 error "too long name registration should fail"
17047
17048         changelog_chmask "MARK+HSM"
17049         lctl get_param mdd.*.changelog*mask
17050         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17051         changelog_users $SINGLEMDS | grep -q $cl_user ||
17052                 error "User $cl_user not found in changelog_users"
17053         #verify username
17054         echo $cl_user | grep -q test_160o ||
17055                 error "User $cl_user has no specific name 'test160o'"
17056
17057         # change something
17058         changelog_clear 0 || error "changelog_clear failed"
17059         # generate some changelog records to accumulate on MDT0
17060         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17061         touch $DIR/$tdir/$tfile                 # open 1
17062
17063         OPENS=$(changelog_dump | grep -c "OPEN")
17064         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17065
17066         # must be no MKDIR it wasn't set as user mask
17067         MKDIR=$(changelog_dump | grep -c "MKDIR")
17068         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17069
17070         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17071                                 mdd.$mdt.changelog_current_mask -n)
17072         # register maskless user
17073         changelog_register || error "changelog_register failed"
17074         # effective mask should be not changed because it is not minimal
17075         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17076                                 mdd.$mdt.changelog_current_mask -n)
17077         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17078         # set server mask to minimal value
17079         changelog_chmask "MARK"
17080         # check effective mask again, should be treated as DEFMASK now
17081         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17082                                 mdd.$mdt.changelog_current_mask -n)
17083         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17084
17085         do_facet $SINGLEMDS $LCTL --device $mdt \
17086                                 changelog_deregister -u test_160o ||
17087                 error "cannot deregister by name"
17088 }
17089 run_test 160o "changelog user name and mask"
17090
17091 test_160p() {
17092         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17093         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17094                 skip "Need MDS version at least 2.14.51"
17095         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17096         local cl_users
17097         local cl_user1
17098         local entry_count
17099
17100         # Create a user
17101         changelog_register || error "first changelog_register failed"
17102
17103         cl_users=(${CL_USERS[mds1]})
17104         cl_user1="${cl_users[0]}"
17105
17106         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17107         createmany -m $DIR/$tdir/$tfile 50 ||
17108                 error "create $DIR/$tdir/$tfile failed"
17109         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17110         rm -rf $DIR/$tdir
17111
17112         # check changelogs have been generated
17113         entry_count=$(changelog_dump | wc -l)
17114         ((entry_count != 0)) || error "no changelog entries found"
17115
17116         # remove changelog_users and check that orphan entries are removed
17117         stop mds1
17118         local dev=$(mdsdevname 1)
17119         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17120         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17121         entry_count=$(changelog_dump | wc -l)
17122         ((entry_count == 0)) ||
17123                 error "found $entry_count changelog entries, expected none"
17124 }
17125 run_test 160p "Changelog orphan cleanup with no users"
17126
17127 test_160q() {
17128         local mdt="$(facet_svc $SINGLEMDS)"
17129         local clu
17130
17131         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17132         remote_mds_nodsh && skip "remote MDS with nodsh"
17133         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17134                 skip "Need MDS version at least 2.14.54"
17135
17136         # set server mask to minimal value like server init does
17137         changelog_chmask "MARK"
17138         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17139                 error "changelog_register failed"
17140         # check effective mask again, should be treated as DEFMASK now
17141         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17142                                 mdd.$mdt.changelog_current_mask -n)
17143         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17144                 error "changelog_deregister failed"
17145         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17146 }
17147 run_test 160q "changelog effective mask is DEFMASK if not set"
17148
17149 test_160s() {
17150         remote_mds_nodsh && skip "remote MDS with nodsh"
17151         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17152                 skip "Need MDS version at least 2.14.55"
17153
17154         local mdts=$(comma_list $(mdts_nodes))
17155
17156         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17157         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17158                                        fail_val=$((24 * 3600 * 10))
17159
17160         # Create a user which is 10 days old
17161         changelog_register || error "first changelog_register failed"
17162         local cl_users
17163         declare -A cl_user1
17164         local i
17165
17166         # generate some changelog records to accumulate on each MDT
17167         # use all_char because created files should be evenly distributed
17168         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17169                 error "test_mkdir $tdir failed"
17170         for ((i = 0; i < MDSCOUNT; i++)); do
17171                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17172                         error "create $DIR/$tdir/d$i.1 failed"
17173         done
17174
17175         # check changelogs have been generated
17176         local nbcl=$(changelog_dump | wc -l)
17177         (( nbcl > 0 )) || error "no changelogs found"
17178
17179         # reduce the max_idle_indexes value to make sure we exceed it
17180         for param in "changelog_max_idle_indexes=2097446912" \
17181                      "changelog_max_idle_time=2592000" \
17182                      "changelog_gc=1" \
17183                      "changelog_min_gc_interval=2"; do
17184                 local MDT0=$(facet_svc $SINGLEMDS)
17185                 local var="${param%=*}"
17186                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17187
17188                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17189                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17190                         error "unable to set mdd.*.$param"
17191         done
17192
17193         local start=$SECONDS
17194         for i in $(seq $MDSCOUNT); do
17195                 cl_users=(${CL_USERS[mds$i]})
17196                 cl_user1[mds$i]="${cl_users[0]}"
17197
17198                 [[ -n "${cl_user1[mds$i]}" ]] ||
17199                         error "mds$i: no user registered"
17200         done
17201
17202         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17203         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17204
17205         # ensure we are past the previous changelog_min_gc_interval set above
17206         local sleep2=$((start + 2 - SECONDS))
17207         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17208
17209         # Generate one more changelog to trigger GC
17210         for ((i = 0; i < MDSCOUNT; i++)); do
17211                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17212                         error "create $DIR/$tdir/d$i.3 failed"
17213         done
17214
17215         # ensure gc thread is done
17216         for node in $(mdts_nodes); do
17217                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17218                         error "$node: GC-thread not done"
17219         done
17220
17221         do_nodes $mdts $LCTL set_param fail_loc=0
17222
17223         for (( i = 1; i <= MDSCOUNT; i++ )); do
17224                 # check cl_user1 is purged
17225                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17226                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17227         done
17228         return 0
17229 }
17230 run_test 160s "changelog garbage collect on idle records * time"
17231
17232 test_160t() {
17233         remote_mds_nodsh && skip "remote MDS with nodsh"
17234         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17235                 skip "Need MDS version at least 2.15.50"
17236
17237         local MDT0=$(facet_svc $SINGLEMDS)
17238         local cl_users
17239         local cl_user1
17240         local cl_user2
17241         local start
17242
17243         changelog_register --user user1 -m all ||
17244                 error "user1 failed to register"
17245
17246         mkdir_on_mdt0 $DIR/$tdir
17247         # create default overstripe to maximize changelog size
17248         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17249         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17250         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17251
17252         # user2 consumes less records so less space
17253         changelog_register --user user2 || error "user2 failed to register"
17254         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17255         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17256
17257         # check changelogs have been generated
17258         local nbcl=$(changelog_dump | wc -l)
17259         (( nbcl > 0 )) || error "no changelogs found"
17260
17261         # reduce the changelog_min_gc_interval to force check
17262         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17263                 local var="${param%=*}"
17264                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17265
17266                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17267                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17268                         error "unable to set mdd.*.$param"
17269         done
17270
17271         start=$SECONDS
17272         cl_users=(${CL_USERS[mds1]})
17273         cl_user1="${cl_users[0]}"
17274         cl_user2="${cl_users[1]}"
17275
17276         [[ -n $cl_user1 ]] ||
17277                 error "mds1: user #1 isn't registered"
17278         [[ -n $cl_user2 ]] ||
17279                 error "mds1: user #2 isn't registered"
17280
17281         # ensure we are past the previous changelog_min_gc_interval set above
17282         local sleep2=$((start + 2 - SECONDS))
17283         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17284
17285         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17286         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17287                         fail_val=$(((llog_size1 + llog_size2) / 2))
17288
17289         # Generate more changelog to trigger GC
17290         createmany -o $DIR/$tdir/u3_ 4 ||
17291                 error "create failed for more files"
17292
17293         # ensure gc thread is done
17294         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17295                 error "mds1: GC-thread not done"
17296
17297         do_facet mds1 $LCTL set_param fail_loc=0
17298
17299         # check cl_user1 is purged
17300         changelog_users mds1 | grep -q "$cl_user1" &&
17301                 error "User $cl_user1 is registered"
17302         # check cl_user2 is not purged
17303         changelog_users mds1 | grep -q "$cl_user2" ||
17304                 error "User $cl_user2 is not registered"
17305 }
17306 run_test 160t "changelog garbage collect on lack of space"
17307
17308 test_161a() {
17309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17310
17311         test_mkdir -c1 $DIR/$tdir
17312         cp /etc/hosts $DIR/$tdir/$tfile
17313         test_mkdir -c1 $DIR/$tdir/foo1
17314         test_mkdir -c1 $DIR/$tdir/foo2
17315         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17316         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17317         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17318         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17319         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17320         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17321                 $LFS fid2path $DIR $FID
17322                 error "bad link ea"
17323         fi
17324         # middle
17325         rm $DIR/$tdir/foo2/zachary
17326         # last
17327         rm $DIR/$tdir/foo2/thor
17328         # first
17329         rm $DIR/$tdir/$tfile
17330         # rename
17331         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17332         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17333                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17334         rm $DIR/$tdir/foo2/maggie
17335
17336         # overflow the EA
17337         local longname=$tfile.avg_len_is_thirty_two_
17338         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17339                 error_noexit 'failed to unlink many hardlinks'" EXIT
17340         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17341                 error "failed to hardlink many files"
17342         links=$($LFS fid2path $DIR $FID | wc -l)
17343         echo -n "${links}/1000 links in link EA"
17344         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17345 }
17346 run_test 161a "link ea sanity"
17347
17348 test_161b() {
17349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17350         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17351
17352         local MDTIDX=1
17353         local remote_dir=$DIR/$tdir/remote_dir
17354
17355         mkdir -p $DIR/$tdir
17356         $LFS mkdir -i $MDTIDX $remote_dir ||
17357                 error "create remote directory failed"
17358
17359         cp /etc/hosts $remote_dir/$tfile
17360         mkdir -p $remote_dir/foo1
17361         mkdir -p $remote_dir/foo2
17362         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17363         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17364         ln $remote_dir/$tfile $remote_dir/foo1/luna
17365         ln $remote_dir/$tfile $remote_dir/foo2/thor
17366
17367         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17368                      tr -d ']')
17369         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17370                 $LFS fid2path $DIR $FID
17371                 error "bad link ea"
17372         fi
17373         # middle
17374         rm $remote_dir/foo2/zachary
17375         # last
17376         rm $remote_dir/foo2/thor
17377         # first
17378         rm $remote_dir/$tfile
17379         # rename
17380         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17381         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17382         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17383                 $LFS fid2path $DIR $FID
17384                 error "bad link rename"
17385         fi
17386         rm $remote_dir/foo2/maggie
17387
17388         # overflow the EA
17389         local longname=filename_avg_len_is_thirty_two_
17390         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17391                 error "failed to hardlink many files"
17392         links=$($LFS fid2path $DIR $FID | wc -l)
17393         echo -n "${links}/1000 links in link EA"
17394         [[ ${links} -gt 60 ]] ||
17395                 error "expected at least 60 links in link EA"
17396         unlinkmany $remote_dir/foo2/$longname 1000 ||
17397         error "failed to unlink many hardlinks"
17398 }
17399 run_test 161b "link ea sanity under remote directory"
17400
17401 test_161c() {
17402         remote_mds_nodsh && skip "remote MDS with nodsh"
17403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17404         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17405                 skip "Need MDS version at least 2.1.5"
17406
17407         # define CLF_RENAME_LAST 0x0001
17408         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17409         changelog_register || error "changelog_register failed"
17410
17411         rm -rf $DIR/$tdir
17412         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17413         touch $DIR/$tdir/foo_161c
17414         touch $DIR/$tdir/bar_161c
17415         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17416         changelog_dump | grep RENME | tail -n 5
17417         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17418         changelog_clear 0 || error "changelog_clear failed"
17419         if [ x$flags != "x0x1" ]; then
17420                 error "flag $flags is not 0x1"
17421         fi
17422
17423         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17424         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17425         touch $DIR/$tdir/foo_161c
17426         touch $DIR/$tdir/bar_161c
17427         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17428         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17429         changelog_dump | grep RENME | tail -n 5
17430         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17431         changelog_clear 0 || error "changelog_clear failed"
17432         if [ x$flags != "x0x0" ]; then
17433                 error "flag $flags is not 0x0"
17434         fi
17435         echo "rename overwrite a target having nlink > 1," \
17436                 "changelog record has flags of $flags"
17437
17438         # rename doesn't overwrite a target (changelog flag 0x0)
17439         touch $DIR/$tdir/foo_161c
17440         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17441         changelog_dump | grep RENME | tail -n 5
17442         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17443         changelog_clear 0 || error "changelog_clear failed"
17444         if [ x$flags != "x0x0" ]; then
17445                 error "flag $flags is not 0x0"
17446         fi
17447         echo "rename doesn't overwrite a target," \
17448                 "changelog record has flags of $flags"
17449
17450         # define CLF_UNLINK_LAST 0x0001
17451         # unlink a file having nlink = 1 (changelog flag 0x1)
17452         rm -f $DIR/$tdir/foo2_161c
17453         changelog_dump | grep UNLNK | tail -n 5
17454         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17455         changelog_clear 0 || error "changelog_clear failed"
17456         if [ x$flags != "x0x1" ]; then
17457                 error "flag $flags is not 0x1"
17458         fi
17459         echo "unlink a file having nlink = 1," \
17460                 "changelog record has flags of $flags"
17461
17462         # unlink a file having nlink > 1 (changelog flag 0x0)
17463         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17464         rm -f $DIR/$tdir/foobar_161c
17465         changelog_dump | grep UNLNK | tail -n 5
17466         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17467         changelog_clear 0 || error "changelog_clear failed"
17468         if [ x$flags != "x0x0" ]; then
17469                 error "flag $flags is not 0x0"
17470         fi
17471         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17472 }
17473 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17474
17475 test_161d() {
17476         remote_mds_nodsh && skip "remote MDS with nodsh"
17477         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17478
17479         local pid
17480         local fid
17481
17482         changelog_register || error "changelog_register failed"
17483
17484         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17485         # interfer with $MOUNT/.lustre/fid/ access
17486         mkdir $DIR/$tdir
17487         [[ $? -eq 0 ]] || error "mkdir failed"
17488
17489         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17490         $LCTL set_param fail_loc=0x8000140c
17491         # 5s pause
17492         $LCTL set_param fail_val=5
17493
17494         # create file
17495         echo foofoo > $DIR/$tdir/$tfile &
17496         pid=$!
17497
17498         # wait for create to be delayed
17499         sleep 2
17500
17501         ps -p $pid
17502         [[ $? -eq 0 ]] || error "create should be blocked"
17503
17504         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17505         stack_trap "rm -f $tempfile"
17506         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17507         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17508         # some delay may occur during ChangeLog publishing and file read just
17509         # above, that could allow file write to happen finally
17510         [[ -s $tempfile ]] && echo "file should be empty"
17511
17512         $LCTL set_param fail_loc=0
17513
17514         wait $pid
17515         [[ $? -eq 0 ]] || error "create failed"
17516 }
17517 run_test 161d "create with concurrent .lustre/fid access"
17518
17519 check_path() {
17520         local expected="$1"
17521         shift
17522         local fid="$2"
17523
17524         local path
17525         path=$($LFS fid2path "$@")
17526         local rc=$?
17527
17528         if [ $rc -ne 0 ]; then
17529                 error "path looked up of '$expected' failed: rc=$rc"
17530         elif [ "$path" != "$expected" ]; then
17531                 error "path looked up '$path' instead of '$expected'"
17532         else
17533                 echo "FID '$fid' resolves to path '$path' as expected"
17534         fi
17535 }
17536
17537 test_162a() { # was test_162
17538         test_mkdir -p -c1 $DIR/$tdir/d2
17539         touch $DIR/$tdir/d2/$tfile
17540         touch $DIR/$tdir/d2/x1
17541         touch $DIR/$tdir/d2/x2
17542         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17543         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17544         # regular file
17545         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17546         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17547
17548         # softlink
17549         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17550         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17551         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17552
17553         # softlink to wrong file
17554         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17555         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17556         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17557
17558         # hardlink
17559         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17560         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17561         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17562         # fid2path dir/fsname should both work
17563         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17564         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17565
17566         # hardlink count: check that there are 2 links
17567         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17568         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17569
17570         # hardlink indexing: remove the first link
17571         rm $DIR/$tdir/d2/p/q/r/hlink
17572         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17573 }
17574 run_test 162a "path lookup sanity"
17575
17576 test_162b() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17579
17580         mkdir $DIR/$tdir
17581         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17582                                 error "create striped dir failed"
17583
17584         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17585                                         tail -n 1 | awk '{print $2}')
17586         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17587
17588         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17589         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17590
17591         # regular file
17592         for ((i=0;i<5;i++)); do
17593                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17594                         error "get fid for f$i failed"
17595                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17596
17597                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17598                         error "get fid for d$i failed"
17599                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17600         done
17601
17602         return 0
17603 }
17604 run_test 162b "striped directory path lookup sanity"
17605
17606 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17607 test_162c() {
17608         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17609                 skip "Need MDS version at least 2.7.51"
17610
17611         local lpath=$tdir.local
17612         local rpath=$tdir.remote
17613
17614         test_mkdir $DIR/$lpath
17615         test_mkdir $DIR/$rpath
17616
17617         for ((i = 0; i <= 101; i++)); do
17618                 lpath="$lpath/$i"
17619                 mkdir $DIR/$lpath
17620                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17621                         error "get fid for local directory $DIR/$lpath failed"
17622                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17623
17624                 rpath="$rpath/$i"
17625                 test_mkdir $DIR/$rpath
17626                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17627                         error "get fid for remote directory $DIR/$rpath failed"
17628                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17629         done
17630
17631         return 0
17632 }
17633 run_test 162c "fid2path works with paths 100 or more directories deep"
17634
17635 oalr_event_count() {
17636         local event="${1}"
17637         local trace="${2}"
17638
17639         awk -v name="${FSNAME}-OST0000" \
17640             -v event="${event}" \
17641             '$1 == "TRACE" && $2 == event && $3 == name' \
17642             "${trace}" |
17643         wc -l
17644 }
17645
17646 oalr_expect_event_count() {
17647         local event="${1}"
17648         local trace="${2}"
17649         local expect="${3}"
17650         local count
17651
17652         count=$(oalr_event_count "${event}" "${trace}")
17653         if ((count == expect)); then
17654                 return 0
17655         fi
17656
17657         error_noexit "${event} event count was '${count}', expected ${expect}"
17658         cat "${trace}" >&2
17659         exit 1
17660 }
17661
17662 cleanup_165() {
17663         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17664         stop ost1
17665         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17666 }
17667
17668 setup_165() {
17669         sync # Flush previous IOs so we can count log entries.
17670         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17671         stack_trap cleanup_165 EXIT
17672 }
17673
17674 test_165a() {
17675         local trace="/tmp/${tfile}.trace"
17676         local rc
17677         local count
17678
17679         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17680                 skip "OFD access log unsupported"
17681
17682         setup_165
17683         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17684         sleep 5
17685
17686         do_facet ost1 ofd_access_log_reader --list
17687         stop ost1
17688
17689         do_facet ost1 killall -TERM ofd_access_log_reader
17690         wait
17691         rc=$?
17692
17693         if ((rc != 0)); then
17694                 error "ofd_access_log_reader exited with rc = '${rc}'"
17695         fi
17696
17697         # Parse trace file for discovery events:
17698         oalr_expect_event_count alr_log_add "${trace}" 1
17699         oalr_expect_event_count alr_log_eof "${trace}" 1
17700         oalr_expect_event_count alr_log_free "${trace}" 1
17701 }
17702 run_test 165a "ofd access log discovery"
17703
17704 test_165b() {
17705         local trace="/tmp/${tfile}.trace"
17706         local file="${DIR}/${tfile}"
17707         local pfid1
17708         local pfid2
17709         local -a entry
17710         local rc
17711         local count
17712         local size
17713         local flags
17714
17715         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17716                 skip "OFD access log unsupported"
17717
17718         setup_165
17719         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17720         sleep 5
17721
17722         do_facet ost1 ofd_access_log_reader --list
17723
17724         lfs setstripe -c 1 -i 0 "${file}"
17725         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17726                 error "cannot create '${file}'"
17727
17728         sleep 5
17729         do_facet ost1 killall -TERM ofd_access_log_reader
17730         wait
17731         rc=$?
17732
17733         if ((rc != 0)); then
17734                 error "ofd_access_log_reader exited with rc = '${rc}'"
17735         fi
17736
17737         oalr_expect_event_count alr_log_entry "${trace}" 1
17738
17739         pfid1=$($LFS path2fid "${file}")
17740
17741         # 1     2             3   4    5     6   7    8    9     10
17742         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17743         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17744
17745         echo "entry = '${entry[*]}'" >&2
17746
17747         pfid2=${entry[4]}
17748         if [[ "${pfid1}" != "${pfid2}" ]]; then
17749                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17750         fi
17751
17752         size=${entry[8]}
17753         if ((size != 1048576)); then
17754                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17755         fi
17756
17757         flags=${entry[10]}
17758         if [[ "${flags}" != "w" ]]; then
17759                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17760         fi
17761
17762         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17763         sleep 5
17764
17765         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17766                 error "cannot read '${file}'"
17767         sleep 5
17768
17769         do_facet ost1 killall -TERM ofd_access_log_reader
17770         wait
17771         rc=$?
17772
17773         if ((rc != 0)); then
17774                 error "ofd_access_log_reader exited with rc = '${rc}'"
17775         fi
17776
17777         oalr_expect_event_count alr_log_entry "${trace}" 1
17778
17779         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17780         echo "entry = '${entry[*]}'" >&2
17781
17782         pfid2=${entry[4]}
17783         if [[ "${pfid1}" != "${pfid2}" ]]; then
17784                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17785         fi
17786
17787         size=${entry[8]}
17788         if ((size != 524288)); then
17789                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17790         fi
17791
17792         flags=${entry[10]}
17793         if [[ "${flags}" != "r" ]]; then
17794                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17795         fi
17796 }
17797 run_test 165b "ofd access log entries are produced and consumed"
17798
17799 test_165c() {
17800         local trace="/tmp/${tfile}.trace"
17801         local file="${DIR}/${tdir}/${tfile}"
17802
17803         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17804                 skip "OFD access log unsupported"
17805
17806         test_mkdir "${DIR}/${tdir}"
17807
17808         setup_165
17809         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17810         sleep 5
17811
17812         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17813
17814         # 4096 / 64 = 64. Create twice as many entries.
17815         for ((i = 0; i < 128; i++)); do
17816                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17817                         error "cannot create file"
17818         done
17819
17820         sync
17821
17822         do_facet ost1 killall -TERM ofd_access_log_reader
17823         wait
17824         rc=$?
17825         if ((rc != 0)); then
17826                 error "ofd_access_log_reader exited with rc = '${rc}'"
17827         fi
17828
17829         unlinkmany  "${file}-%d" 128
17830 }
17831 run_test 165c "full ofd access logs do not block IOs"
17832
17833 oal_get_read_count() {
17834         local stats="$1"
17835
17836         # STATS lustre-OST0001 alr_read_count 1
17837
17838         do_facet ost1 cat "${stats}" |
17839         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17840              END { print count; }'
17841 }
17842
17843 oal_expect_read_count() {
17844         local stats="$1"
17845         local count
17846         local expect="$2"
17847
17848         # Ask ofd_access_log_reader to write stats.
17849         do_facet ost1 killall -USR1 ofd_access_log_reader
17850
17851         # Allow some time for things to happen.
17852         sleep 1
17853
17854         count=$(oal_get_read_count "${stats}")
17855         if ((count == expect)); then
17856                 return 0
17857         fi
17858
17859         error_noexit "bad read count, got ${count}, expected ${expect}"
17860         do_facet ost1 cat "${stats}" >&2
17861         exit 1
17862 }
17863
17864 test_165d() {
17865         local stats="/tmp/${tfile}.stats"
17866         local file="${DIR}/${tdir}/${tfile}"
17867         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17868
17869         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17870                 skip "OFD access log unsupported"
17871
17872         test_mkdir "${DIR}/${tdir}"
17873
17874         setup_165
17875         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17876         sleep 5
17877
17878         lfs setstripe -c 1 -i 0 "${file}"
17879
17880         do_facet ost1 lctl set_param "${param}=rw"
17881         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17882                 error "cannot create '${file}'"
17883         oal_expect_read_count "${stats}" 1
17884
17885         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17886                 error "cannot read '${file}'"
17887         oal_expect_read_count "${stats}" 2
17888
17889         do_facet ost1 lctl set_param "${param}=r"
17890         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17891                 error "cannot create '${file}'"
17892         oal_expect_read_count "${stats}" 2
17893
17894         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17895                 error "cannot read '${file}'"
17896         oal_expect_read_count "${stats}" 3
17897
17898         do_facet ost1 lctl set_param "${param}=w"
17899         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17900                 error "cannot create '${file}'"
17901         oal_expect_read_count "${stats}" 4
17902
17903         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17904                 error "cannot read '${file}'"
17905         oal_expect_read_count "${stats}" 4
17906
17907         do_facet ost1 lctl set_param "${param}=0"
17908         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17909                 error "cannot create '${file}'"
17910         oal_expect_read_count "${stats}" 4
17911
17912         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17913                 error "cannot read '${file}'"
17914         oal_expect_read_count "${stats}" 4
17915
17916         do_facet ost1 killall -TERM ofd_access_log_reader
17917         wait
17918         rc=$?
17919         if ((rc != 0)); then
17920                 error "ofd_access_log_reader exited with rc = '${rc}'"
17921         fi
17922 }
17923 run_test 165d "ofd_access_log mask works"
17924
17925 test_165e() {
17926         local stats="/tmp/${tfile}.stats"
17927         local file0="${DIR}/${tdir}-0/${tfile}"
17928         local file1="${DIR}/${tdir}-1/${tfile}"
17929
17930         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17931                 skip "OFD access log unsupported"
17932
17933         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17934
17935         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17936         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17937
17938         lfs setstripe -c 1 -i 0 "${file0}"
17939         lfs setstripe -c 1 -i 0 "${file1}"
17940
17941         setup_165
17942         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17943         sleep 5
17944
17945         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17946                 error "cannot create '${file0}'"
17947         sync
17948         oal_expect_read_count "${stats}" 0
17949
17950         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17951                 error "cannot create '${file1}'"
17952         sync
17953         oal_expect_read_count "${stats}" 1
17954
17955         do_facet ost1 killall -TERM ofd_access_log_reader
17956         wait
17957         rc=$?
17958         if ((rc != 0)); then
17959                 error "ofd_access_log_reader exited with rc = '${rc}'"
17960         fi
17961 }
17962 run_test 165e "ofd_access_log MDT index filter works"
17963
17964 test_165f() {
17965         local trace="/tmp/${tfile}.trace"
17966         local rc
17967         local count
17968
17969         setup_165
17970         do_facet ost1 timeout 60 ofd_access_log_reader \
17971                 --exit-on-close --debug=- --trace=- > "${trace}" &
17972         sleep 5
17973         stop ost1
17974
17975         wait
17976         rc=$?
17977
17978         if ((rc != 0)); then
17979                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17980                 cat "${trace}"
17981                 exit 1
17982         fi
17983 }
17984 run_test 165f "ofd_access_log_reader --exit-on-close works"
17985
17986 test_169() {
17987         # do directio so as not to populate the page cache
17988         log "creating a 10 Mb file"
17989         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17990                 error "multiop failed while creating a file"
17991         log "starting reads"
17992         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17993         log "truncating the file"
17994         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17995                 error "multiop failed while truncating the file"
17996         log "killing dd"
17997         kill %+ || true # reads might have finished
17998         echo "wait until dd is finished"
17999         wait
18000         log "removing the temporary file"
18001         rm -rf $DIR/$tfile || error "tmp file removal failed"
18002 }
18003 run_test 169 "parallel read and truncate should not deadlock"
18004
18005 test_170() {
18006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18007
18008         $LCTL clear     # bug 18514
18009         $LCTL debug_daemon start $TMP/${tfile}_log_good
18010         touch $DIR/$tfile
18011         $LCTL debug_daemon stop
18012         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18013                 error "sed failed to read log_good"
18014
18015         $LCTL debug_daemon start $TMP/${tfile}_log_good
18016         rm -rf $DIR/$tfile
18017         $LCTL debug_daemon stop
18018
18019         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18020                error "lctl df log_bad failed"
18021
18022         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18023         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18024
18025         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18026         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18027
18028         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18029                 error "bad_line good_line1 good_line2 are empty"
18030
18031         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18032         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18033         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18034
18035         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18036         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18037         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18038
18039         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18040                 error "bad_line_new good_line_new are empty"
18041
18042         local expected_good=$((good_line1 + good_line2*2))
18043
18044         rm -f $TMP/${tfile}*
18045         # LU-231, short malformed line may not be counted into bad lines
18046         if [ $bad_line -ne $bad_line_new ] &&
18047                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18048                 error "expected $bad_line bad lines, but got $bad_line_new"
18049                 return 1
18050         fi
18051
18052         if [ $expected_good -ne $good_line_new ]; then
18053                 error "expected $expected_good good lines, but got $good_line_new"
18054                 return 2
18055         fi
18056         true
18057 }
18058 run_test 170 "test lctl df to handle corrupted log ====================="
18059
18060 test_171() { # bug20592
18061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18062
18063         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18064         $LCTL set_param fail_loc=0x50e
18065         $LCTL set_param fail_val=3000
18066         multiop_bg_pause $DIR/$tfile O_s || true
18067         local MULTIPID=$!
18068         kill -USR1 $MULTIPID
18069         # cause log dump
18070         sleep 3
18071         wait $MULTIPID
18072         if dmesg | grep "recursive fault"; then
18073                 error "caught a recursive fault"
18074         fi
18075         $LCTL set_param fail_loc=0
18076         true
18077 }
18078 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18079
18080 test_172() {
18081
18082         #define OBD_FAIL_OBD_CLEANUP  0x60e
18083         $LCTL set_param fail_loc=0x60e
18084         umount $MOUNT || error "umount $MOUNT failed"
18085         stack_trap "mount_client $MOUNT"
18086
18087         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18088                 error "no client OBDs are remained"
18089
18090         $LCTL dl | while read devno state type name foo; do
18091                 case $type in
18092                 lov|osc|lmv|mdc)
18093                         $LCTL --device $name cleanup
18094                         $LCTL --device $name detach
18095                         ;;
18096                 *)
18097                         # skip server devices
18098                         ;;
18099                 esac
18100         done
18101
18102         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18103                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18104                 error "some client OBDs are still remained"
18105         fi
18106
18107 }
18108 run_test 172 "manual device removal with lctl cleanup/detach ======"
18109
18110 # it would be good to share it with obdfilter-survey/iokit-libecho code
18111 setup_obdecho_osc () {
18112         local rc=0
18113         local ost_nid=$1
18114         local obdfilter_name=$2
18115         echo "Creating new osc for $obdfilter_name on $ost_nid"
18116         # make sure we can find loopback nid
18117         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18118
18119         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18120                            ${obdfilter_name}_osc_UUID || rc=2; }
18121         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18122                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18123         return $rc
18124 }
18125
18126 cleanup_obdecho_osc () {
18127         local obdfilter_name=$1
18128         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18129         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18130         return 0
18131 }
18132
18133 obdecho_test() {
18134         local OBD=$1
18135         local node=$2
18136         local pages=${3:-64}
18137         local rc=0
18138         local id
18139
18140         local count=10
18141         local obd_size=$(get_obd_size $node $OBD)
18142         local page_size=$(get_page_size $node)
18143         if [[ -n "$obd_size" ]]; then
18144                 local new_count=$((obd_size / (pages * page_size / 1024)))
18145                 [[ $new_count -ge $count ]] || count=$new_count
18146         fi
18147
18148         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18149         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18150                            rc=2; }
18151         if [ $rc -eq 0 ]; then
18152             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18153             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18154         fi
18155         echo "New object id is $id"
18156         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18157                            rc=4; }
18158         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18159                            "test_brw $count w v $pages $id" || rc=4; }
18160         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18161                            rc=4; }
18162         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18163                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18164         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18165                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18166         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18167         return $rc
18168 }
18169
18170 test_180a() {
18171         skip "obdecho on osc is no longer supported"
18172 }
18173 run_test 180a "test obdecho on osc"
18174
18175 test_180b() {
18176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18177         remote_ost_nodsh && skip "remote OST with nodsh"
18178
18179         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18180                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18181                 error "failed to load module obdecho"
18182
18183         local target=$(do_facet ost1 $LCTL dl |
18184                        awk '/obdfilter/ { print $4; exit; }')
18185
18186         if [ -n "$target" ]; then
18187                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18188         else
18189                 do_facet ost1 $LCTL dl
18190                 error "there is no obdfilter target on ost1"
18191         fi
18192 }
18193 run_test 180b "test obdecho directly on obdfilter"
18194
18195 test_180c() { # LU-2598
18196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18197         remote_ost_nodsh && skip "remote OST with nodsh"
18198         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18199                 skip "Need MDS version at least 2.4.0"
18200
18201         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18202                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18203                 error "failed to load module obdecho"
18204
18205         local target=$(do_facet ost1 $LCTL dl |
18206                        awk '/obdfilter/ { print $4; exit; }')
18207
18208         if [ -n "$target" ]; then
18209                 local pages=16384 # 64MB bulk I/O RPC size
18210
18211                 obdecho_test "$target" ost1 "$pages" ||
18212                         error "obdecho_test with pages=$pages failed with $?"
18213         else
18214                 do_facet ost1 $LCTL dl
18215                 error "there is no obdfilter target on ost1"
18216         fi
18217 }
18218 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18219
18220 test_181() { # bug 22177
18221         test_mkdir $DIR/$tdir
18222         # create enough files to index the directory
18223         createmany -o $DIR/$tdir/foobar 4000
18224         # print attributes for debug purpose
18225         lsattr -d .
18226         # open dir
18227         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18228         MULTIPID=$!
18229         # remove the files & current working dir
18230         unlinkmany $DIR/$tdir/foobar 4000
18231         rmdir $DIR/$tdir
18232         kill -USR1 $MULTIPID
18233         wait $MULTIPID
18234         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18235         return 0
18236 }
18237 run_test 181 "Test open-unlinked dir ========================"
18238
18239 test_182a() {
18240         local fcount=1000
18241         local tcount=10
18242
18243         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18244
18245         $LCTL set_param mdc.*.rpc_stats=clear
18246
18247         for (( i = 0; i < $tcount; i++ )) ; do
18248                 mkdir $DIR/$tdir/$i
18249         done
18250
18251         for (( i = 0; i < $tcount; i++ )) ; do
18252                 createmany -o $DIR/$tdir/$i/f- $fcount &
18253         done
18254         wait
18255
18256         for (( i = 0; i < $tcount; i++ )) ; do
18257                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18258         done
18259         wait
18260
18261         $LCTL get_param mdc.*.rpc_stats
18262
18263         rm -rf $DIR/$tdir
18264 }
18265 run_test 182a "Test parallel modify metadata operations from mdc"
18266
18267 test_182b() {
18268         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18269         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18270         local dcount=1000
18271         local tcount=10
18272         local stime
18273         local etime
18274         local delta
18275
18276         do_facet mds1 $LCTL list_param \
18277                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18278                 skip "MDS lacks parallel RPC handling"
18279
18280         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18281
18282         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18283                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18284
18285         stime=$(date +%s)
18286         createmany -i 0 -d $DIR/$tdir/t- $tcount
18287
18288         for (( i = 0; i < $tcount; i++ )) ; do
18289                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18290         done
18291         wait
18292         etime=$(date +%s)
18293         delta=$((etime - stime))
18294         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18295
18296         stime=$(date +%s)
18297         for (( i = 0; i < $tcount; i++ )) ; do
18298                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18299         done
18300         wait
18301         etime=$(date +%s)
18302         delta=$((etime - stime))
18303         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18304
18305         rm -rf $DIR/$tdir
18306
18307         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18308
18309         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18310
18311         stime=$(date +%s)
18312         createmany -i 0 -d $DIR/$tdir/t- $tcount
18313
18314         for (( i = 0; i < $tcount; i++ )) ; do
18315                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18316         done
18317         wait
18318         etime=$(date +%s)
18319         delta=$((etime - stime))
18320         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18321
18322         stime=$(date +%s)
18323         for (( i = 0; i < $tcount; i++ )) ; do
18324                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18325         done
18326         wait
18327         etime=$(date +%s)
18328         delta=$((etime - stime))
18329         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18330
18331         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18332 }
18333 run_test 182b "Test parallel modify metadata operations from osp"
18334
18335 test_183() { # LU-2275
18336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18337         remote_mds_nodsh && skip "remote MDS with nodsh"
18338         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18339                 skip "Need MDS version at least 2.3.56"
18340
18341         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18342         echo aaa > $DIR/$tdir/$tfile
18343
18344 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18345         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18346
18347         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18348         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18349
18350         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18351
18352         # Flush negative dentry cache
18353         touch $DIR/$tdir/$tfile
18354
18355         # We are not checking for any leaked references here, they'll
18356         # become evident next time we do cleanup with module unload.
18357         rm -rf $DIR/$tdir
18358 }
18359 run_test 183 "No crash or request leak in case of strange dispositions ========"
18360
18361 # test suite 184 is for LU-2016, LU-2017
18362 test_184a() {
18363         check_swap_layouts_support
18364
18365         dir0=$DIR/$tdir/$testnum
18366         test_mkdir -p -c1 $dir0
18367         ref1=/etc/passwd
18368         ref2=/etc/group
18369         file1=$dir0/f1
18370         file2=$dir0/f2
18371         $LFS setstripe -c1 $file1
18372         cp $ref1 $file1
18373         $LFS setstripe -c2 $file2
18374         cp $ref2 $file2
18375         gen1=$($LFS getstripe -g $file1)
18376         gen2=$($LFS getstripe -g $file2)
18377
18378         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18379         gen=$($LFS getstripe -g $file1)
18380         [[ $gen1 != $gen ]] ||
18381                 error "Layout generation on $file1 does not change"
18382         gen=$($LFS getstripe -g $file2)
18383         [[ $gen2 != $gen ]] ||
18384                 error "Layout generation on $file2 does not change"
18385
18386         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18387         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18388
18389         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18390 }
18391 run_test 184a "Basic layout swap"
18392
18393 test_184b() {
18394         check_swap_layouts_support
18395
18396         dir0=$DIR/$tdir/$testnum
18397         mkdir -p $dir0 || error "creating dir $dir0"
18398         file1=$dir0/f1
18399         file2=$dir0/f2
18400         file3=$dir0/f3
18401         dir1=$dir0/d1
18402         dir2=$dir0/d2
18403         mkdir $dir1 $dir2
18404         $LFS setstripe -c1 $file1
18405         $LFS setstripe -c2 $file2
18406         $LFS setstripe -c1 $file3
18407         chown $RUNAS_ID $file3
18408         gen1=$($LFS getstripe -g $file1)
18409         gen2=$($LFS getstripe -g $file2)
18410
18411         $LFS swap_layouts $dir1 $dir2 &&
18412                 error "swap of directories layouts should fail"
18413         $LFS swap_layouts $dir1 $file1 &&
18414                 error "swap of directory and file layouts should fail"
18415         $RUNAS $LFS swap_layouts $file1 $file2 &&
18416                 error "swap of file we cannot write should fail"
18417         $LFS swap_layouts $file1 $file3 &&
18418                 error "swap of file with different owner should fail"
18419         /bin/true # to clear error code
18420 }
18421 run_test 184b "Forbidden layout swap (will generate errors)"
18422
18423 test_184c() {
18424         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18425         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18426         check_swap_layouts_support
18427         check_swap_layout_no_dom $DIR
18428
18429         local dir0=$DIR/$tdir/$testnum
18430         mkdir -p $dir0 || error "creating dir $dir0"
18431
18432         local ref1=$dir0/ref1
18433         local ref2=$dir0/ref2
18434         local file1=$dir0/file1
18435         local file2=$dir0/file2
18436         # create a file large enough for the concurrent test
18437         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18438         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18439         echo "ref file size: ref1($(stat -c %s $ref1))," \
18440              "ref2($(stat -c %s $ref2))"
18441
18442         cp $ref2 $file2
18443         dd if=$ref1 of=$file1 bs=16k &
18444         local DD_PID=$!
18445
18446         # Make sure dd starts to copy file, but wait at most 5 seconds
18447         local loops=0
18448         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18449
18450         $LFS swap_layouts $file1 $file2
18451         local rc=$?
18452         wait $DD_PID
18453         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18454         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18455
18456         # how many bytes copied before swapping layout
18457         local copied=$(stat -c %s $file2)
18458         local remaining=$(stat -c %s $ref1)
18459         remaining=$((remaining - copied))
18460         echo "Copied $copied bytes before swapping layout..."
18461
18462         cmp -n $copied $file1 $ref2 | grep differ &&
18463                 error "Content mismatch [0, $copied) of ref2 and file1"
18464         cmp -n $copied $file2 $ref1 ||
18465                 error "Content mismatch [0, $copied) of ref1 and file2"
18466         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18467                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18468
18469         # clean up
18470         rm -f $ref1 $ref2 $file1 $file2
18471 }
18472 run_test 184c "Concurrent write and layout swap"
18473
18474 test_184d() {
18475         check_swap_layouts_support
18476         check_swap_layout_no_dom $DIR
18477         [ -z "$(which getfattr 2>/dev/null)" ] &&
18478                 skip_env "no getfattr command"
18479
18480         local file1=$DIR/$tdir/$tfile-1
18481         local file2=$DIR/$tdir/$tfile-2
18482         local file3=$DIR/$tdir/$tfile-3
18483         local lovea1
18484         local lovea2
18485
18486         mkdir -p $DIR/$tdir
18487         touch $file1 || error "create $file1 failed"
18488         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18489                 error "create $file2 failed"
18490         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18491                 error "create $file3 failed"
18492         lovea1=$(get_layout_param $file1)
18493
18494         $LFS swap_layouts $file2 $file3 ||
18495                 error "swap $file2 $file3 layouts failed"
18496         $LFS swap_layouts $file1 $file2 ||
18497                 error "swap $file1 $file2 layouts failed"
18498
18499         lovea2=$(get_layout_param $file2)
18500         echo "$lovea1"
18501         echo "$lovea2"
18502         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18503
18504         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18505         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18506 }
18507 run_test 184d "allow stripeless layouts swap"
18508
18509 test_184e() {
18510         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18511                 skip "Need MDS version at least 2.6.94"
18512         check_swap_layouts_support
18513         check_swap_layout_no_dom $DIR
18514         [ -z "$(which getfattr 2>/dev/null)" ] &&
18515                 skip_env "no getfattr command"
18516
18517         local file1=$DIR/$tdir/$tfile-1
18518         local file2=$DIR/$tdir/$tfile-2
18519         local file3=$DIR/$tdir/$tfile-3
18520         local lovea
18521
18522         mkdir -p $DIR/$tdir
18523         touch $file1 || error "create $file1 failed"
18524         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18525                 error "create $file2 failed"
18526         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18527                 error "create $file3 failed"
18528
18529         $LFS swap_layouts $file1 $file2 ||
18530                 error "swap $file1 $file2 layouts failed"
18531
18532         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18533         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18534
18535         echo 123 > $file1 || error "Should be able to write into $file1"
18536
18537         $LFS swap_layouts $file1 $file3 ||
18538                 error "swap $file1 $file3 layouts failed"
18539
18540         echo 123 > $file1 || error "Should be able to write into $file1"
18541
18542         rm -rf $file1 $file2 $file3
18543 }
18544 run_test 184e "Recreate layout after stripeless layout swaps"
18545
18546 test_184f() {
18547         # Create a file with name longer than sizeof(struct stat) ==
18548         # 144 to see if we can get chars from the file name to appear
18549         # in the returned striping. Note that 'f' == 0x66.
18550         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18551
18552         mkdir -p $DIR/$tdir
18553         mcreate $DIR/$tdir/$file
18554         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18555                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18556         fi
18557 }
18558 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18559
18560 test_185() { # LU-2441
18561         # LU-3553 - no volatile file support in old servers
18562         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18563                 skip "Need MDS version at least 2.3.60"
18564
18565         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18566         touch $DIR/$tdir/spoo
18567         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18568         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18569                 error "cannot create/write a volatile file"
18570         [ "$FILESET" == "" ] &&
18571         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18572                 error "FID is still valid after close"
18573
18574         multiop_bg_pause $DIR/$tdir vVw4096_c
18575         local multi_pid=$!
18576
18577         local OLD_IFS=$IFS
18578         IFS=":"
18579         local fidv=($fid)
18580         IFS=$OLD_IFS
18581         # assume that the next FID for this client is sequential, since stdout
18582         # is unfortunately eaten by multiop_bg_pause
18583         local n=$((${fidv[1]} + 1))
18584         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18585         if [ "$FILESET" == "" ]; then
18586                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18587                         error "FID is missing before close"
18588         fi
18589         kill -USR1 $multi_pid
18590         # 1 second delay, so if mtime change we will see it
18591         sleep 1
18592         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18593         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18594 }
18595 run_test 185 "Volatile file support"
18596
18597 function create_check_volatile() {
18598         local idx=$1
18599         local tgt
18600
18601         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18602         local PID=$!
18603         sleep 1
18604         local FID=$(cat /tmp/${tfile}.fid)
18605         [ "$FID" == "" ] && error "can't get FID for volatile"
18606         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18607         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18608         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18609         kill -USR1 $PID
18610         wait
18611         sleep 1
18612         cancel_lru_locks mdc # flush opencache
18613         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18614         return 0
18615 }
18616
18617 test_185a(){
18618         # LU-12516 - volatile creation via .lustre
18619         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18620                 skip "Need MDS version at least 2.3.55"
18621
18622         create_check_volatile 0
18623         [ $MDSCOUNT -lt 2 ] && return 0
18624
18625         # DNE case
18626         create_check_volatile 1
18627
18628         return 0
18629 }
18630 run_test 185a "Volatile file creation in .lustre/fid/"
18631
18632 test_187a() {
18633         remote_mds_nodsh && skip "remote MDS with nodsh"
18634         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18635                 skip "Need MDS version at least 2.3.0"
18636
18637         local dir0=$DIR/$tdir/$testnum
18638         mkdir -p $dir0 || error "creating dir $dir0"
18639
18640         local file=$dir0/file1
18641         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18642         local dv1=$($LFS data_version $file)
18643         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18644         local dv2=$($LFS data_version $file)
18645         [[ $dv1 != $dv2 ]] ||
18646                 error "data version did not change on write $dv1 == $dv2"
18647
18648         # clean up
18649         rm -f $file1
18650 }
18651 run_test 187a "Test data version change"
18652
18653 test_187b() {
18654         remote_mds_nodsh && skip "remote MDS with nodsh"
18655         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18656                 skip "Need MDS version at least 2.3.0"
18657
18658         local dir0=$DIR/$tdir/$testnum
18659         mkdir -p $dir0 || error "creating dir $dir0"
18660
18661         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18662         [[ ${DV[0]} != ${DV[1]} ]] ||
18663                 error "data version did not change on write"\
18664                       " ${DV[0]} == ${DV[1]}"
18665
18666         # clean up
18667         rm -f $file1
18668 }
18669 run_test 187b "Test data version change on volatile file"
18670
18671 test_200() {
18672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18673         remote_mgs_nodsh && skip "remote MGS with nodsh"
18674         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18675
18676         local POOL=${POOL:-cea1}
18677         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18678         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18679         # Pool OST targets
18680         local first_ost=0
18681         local last_ost=$(($OSTCOUNT - 1))
18682         local ost_step=2
18683         local ost_list=$(seq $first_ost $ost_step $last_ost)
18684         local ost_range="$first_ost $last_ost $ost_step"
18685         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18686         local file_dir=$POOL_ROOT/file_tst
18687         local subdir=$test_path/subdir
18688         local rc=0
18689
18690         while : ; do
18691                 # former test_200a test_200b
18692                 pool_add $POOL                          || { rc=$? ; break; }
18693                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18694                 # former test_200c test_200d
18695                 mkdir -p $test_path
18696                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18697                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18698                 mkdir -p $subdir
18699                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18700                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18701                                                         || { rc=$? ; break; }
18702                 # former test_200e test_200f
18703                 local files=$((OSTCOUNT*3))
18704                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18705                                                         || { rc=$? ; break; }
18706                 pool_create_files $POOL $file_dir $files "$ost_list" \
18707                                                         || { rc=$? ; break; }
18708                 # former test_200g test_200h
18709                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18710                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18711
18712                 # former test_201a test_201b test_201c
18713                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18714
18715                 local f=$test_path/$tfile
18716                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18717                 pool_remove $POOL $f                    || { rc=$? ; break; }
18718                 break
18719         done
18720
18721         destroy_test_pools
18722
18723         return $rc
18724 }
18725 run_test 200 "OST pools"
18726
18727 # usage: default_attr <count | size | offset>
18728 default_attr() {
18729         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18730 }
18731
18732 # usage: check_default_stripe_attr
18733 check_default_stripe_attr() {
18734         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18735         case $1 in
18736         --stripe-count|-c)
18737                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18738         --stripe-size|-S)
18739                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18740         --stripe-index|-i)
18741                 EXPECTED=-1;;
18742         *)
18743                 error "unknown getstripe attr '$1'"
18744         esac
18745
18746         [ $ACTUAL == $EXPECTED ] ||
18747                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18748 }
18749
18750 test_204a() {
18751         test_mkdir $DIR/$tdir
18752         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18753
18754         check_default_stripe_attr --stripe-count
18755         check_default_stripe_attr --stripe-size
18756         check_default_stripe_attr --stripe-index
18757 }
18758 run_test 204a "Print default stripe attributes"
18759
18760 test_204b() {
18761         test_mkdir $DIR/$tdir
18762         $LFS setstripe --stripe-count 1 $DIR/$tdir
18763
18764         check_default_stripe_attr --stripe-size
18765         check_default_stripe_attr --stripe-index
18766 }
18767 run_test 204b "Print default stripe size and offset"
18768
18769 test_204c() {
18770         test_mkdir $DIR/$tdir
18771         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18772
18773         check_default_stripe_attr --stripe-count
18774         check_default_stripe_attr --stripe-index
18775 }
18776 run_test 204c "Print default stripe count and offset"
18777
18778 test_204d() {
18779         test_mkdir $DIR/$tdir
18780         $LFS setstripe --stripe-index 0 $DIR/$tdir
18781
18782         check_default_stripe_attr --stripe-count
18783         check_default_stripe_attr --stripe-size
18784 }
18785 run_test 204d "Print default stripe count and size"
18786
18787 test_204e() {
18788         test_mkdir $DIR/$tdir
18789         $LFS setstripe -d $DIR/$tdir
18790
18791         check_default_stripe_attr --stripe-count --raw
18792         check_default_stripe_attr --stripe-size --raw
18793         check_default_stripe_attr --stripe-index --raw
18794 }
18795 run_test 204e "Print raw stripe attributes"
18796
18797 test_204f() {
18798         test_mkdir $DIR/$tdir
18799         $LFS setstripe --stripe-count 1 $DIR/$tdir
18800
18801         check_default_stripe_attr --stripe-size --raw
18802         check_default_stripe_attr --stripe-index --raw
18803 }
18804 run_test 204f "Print raw stripe size and offset"
18805
18806 test_204g() {
18807         test_mkdir $DIR/$tdir
18808         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18809
18810         check_default_stripe_attr --stripe-count --raw
18811         check_default_stripe_attr --stripe-index --raw
18812 }
18813 run_test 204g "Print raw stripe count and offset"
18814
18815 test_204h() {
18816         test_mkdir $DIR/$tdir
18817         $LFS setstripe --stripe-index 0 $DIR/$tdir
18818
18819         check_default_stripe_attr --stripe-count --raw
18820         check_default_stripe_attr --stripe-size --raw
18821 }
18822 run_test 204h "Print raw stripe count and size"
18823
18824 # Figure out which job scheduler is being used, if any,
18825 # or use a fake one
18826 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18827         JOBENV=SLURM_JOB_ID
18828 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18829         JOBENV=LSB_JOBID
18830 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18831         JOBENV=PBS_JOBID
18832 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18833         JOBENV=LOADL_STEP_ID
18834 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18835         JOBENV=JOB_ID
18836 else
18837         $LCTL list_param jobid_name > /dev/null 2>&1
18838         if [ $? -eq 0 ]; then
18839                 JOBENV=nodelocal
18840         else
18841                 JOBENV=FAKE_JOBID
18842         fi
18843 fi
18844 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18845
18846 verify_jobstats() {
18847         local cmd=($1)
18848         shift
18849         local facets="$@"
18850
18851 # we don't really need to clear the stats for this test to work, since each
18852 # command has a unique jobid, but it makes debugging easier if needed.
18853 #       for facet in $facets; do
18854 #               local dev=$(convert_facet2label $facet)
18855 #               # clear old jobstats
18856 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18857 #       done
18858
18859         # use a new JobID for each test, or we might see an old one
18860         [ "$JOBENV" = "FAKE_JOBID" ] &&
18861                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18862
18863         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18864
18865         [ "$JOBENV" = "nodelocal" ] && {
18866                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18867                 $LCTL set_param jobid_name=$FAKE_JOBID
18868                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18869         }
18870
18871         log "Test: ${cmd[*]}"
18872         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18873
18874         if [ $JOBENV = "FAKE_JOBID" ]; then
18875                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18876         else
18877                 ${cmd[*]}
18878         fi
18879
18880         # all files are created on OST0000
18881         for facet in $facets; do
18882                 local stats="*.$(convert_facet2label $facet).job_stats"
18883
18884                 # strip out libtool wrappers for in-tree executables
18885                 if (( $(do_facet $facet lctl get_param $stats |
18886                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18887                         do_facet $facet lctl get_param $stats
18888                         error "No jobstats for $JOBVAL found on $facet::$stats"
18889                 fi
18890         done
18891 }
18892
18893 jobstats_set() {
18894         local new_jobenv=$1
18895
18896         set_persistent_param_and_check client "jobid_var" \
18897                 "$FSNAME.sys.jobid_var" $new_jobenv
18898 }
18899
18900 test_205a() { # Job stats
18901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18902         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18903                 skip "Need MDS version with at least 2.7.1"
18904         remote_mgs_nodsh && skip "remote MGS with nodsh"
18905         remote_mds_nodsh && skip "remote MDS with nodsh"
18906         remote_ost_nodsh && skip "remote OST with nodsh"
18907         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18908                 skip "Server doesn't support jobstats"
18909         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18910
18911         local old_jobenv=$($LCTL get_param -n jobid_var)
18912         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18913
18914         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18915                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18916         else
18917                 stack_trap "do_facet mgs $PERM_CMD \
18918                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18919         fi
18920         changelog_register
18921
18922         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18923                                 mdt.*.job_cleanup_interval | head -n 1)
18924         local new_interval=5
18925         do_facet $SINGLEMDS \
18926                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18927         stack_trap "do_facet $SINGLEMDS \
18928                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18929         local start=$SECONDS
18930
18931         local cmd
18932         # mkdir
18933         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18934         verify_jobstats "$cmd" "$SINGLEMDS"
18935         # rmdir
18936         cmd="rmdir $DIR/$tdir"
18937         verify_jobstats "$cmd" "$SINGLEMDS"
18938         # mkdir on secondary MDT
18939         if [ $MDSCOUNT -gt 1 ]; then
18940                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18941                 verify_jobstats "$cmd" "mds2"
18942         fi
18943         # mknod
18944         cmd="mknod $DIR/$tfile c 1 3"
18945         verify_jobstats "$cmd" "$SINGLEMDS"
18946         # unlink
18947         cmd="rm -f $DIR/$tfile"
18948         verify_jobstats "$cmd" "$SINGLEMDS"
18949         # create all files on OST0000 so verify_jobstats can find OST stats
18950         # open & close
18951         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18952         verify_jobstats "$cmd" "$SINGLEMDS"
18953         # setattr
18954         cmd="touch $DIR/$tfile"
18955         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18956         # write
18957         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18958         verify_jobstats "$cmd" "ost1"
18959         # read
18960         cancel_lru_locks osc
18961         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18962         verify_jobstats "$cmd" "ost1"
18963         # truncate
18964         cmd="$TRUNCATE $DIR/$tfile 0"
18965         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18966         # rename
18967         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18968         verify_jobstats "$cmd" "$SINGLEMDS"
18969         # jobstats expiry - sleep until old stats should be expired
18970         local left=$((new_interval + 5 - (SECONDS - start)))
18971         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18972                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18973                         "0" $left
18974         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18975         verify_jobstats "$cmd" "$SINGLEMDS"
18976         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18977             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18978
18979         # Ensure that jobid are present in changelog (if supported by MDS)
18980         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18981                 changelog_dump | tail -10
18982                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18983                 [ $jobids -eq 9 ] ||
18984                         error "Wrong changelog jobid count $jobids != 9"
18985
18986                 # LU-5862
18987                 JOBENV="disable"
18988                 jobstats_set $JOBENV
18989                 touch $DIR/$tfile
18990                 changelog_dump | grep $tfile
18991                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18992                 [ $jobids -eq 0 ] ||
18993                         error "Unexpected jobids when jobid_var=$JOBENV"
18994         fi
18995
18996         # test '%j' access to environment variable - if supported
18997         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18998                 JOBENV="JOBCOMPLEX"
18999                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19000
19001                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19002         fi
19003
19004         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19005                 JOBENV="JOBCOMPLEX"
19006                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19007
19008                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19009         fi
19010
19011         # test '%j' access to per-session jobid - if supported
19012         if lctl list_param jobid_this_session > /dev/null 2>&1
19013         then
19014                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19015                 lctl set_param jobid_this_session=$USER
19016
19017                 JOBENV="JOBCOMPLEX"
19018                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19019
19020                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19021         fi
19022 }
19023 run_test 205a "Verify job stats"
19024
19025 # LU-13117, LU-13597
19026 test_205b() {
19027         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19028                 skip "Need MDS version at least 2.13.54.91"
19029
19030         local job_stats="mdt.*.job_stats"
19031         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19032
19033         do_facet mds1 $LCTL set_param $job_stats=clear
19034
19035         # Setting jobid_var to USER might not be supported
19036         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19037         $LCTL set_param jobid_var=USER || true
19038         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19039         $LCTL set_param jobid_name="%j.%e.%u"
19040
19041         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19042         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19043                 { do_facet mds1 $LCTL get_param $job_stats;
19044                   error "Unexpected jobid found"; }
19045         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19046                 { do_facet mds1 $LCTL get_param $job_stats;
19047                   error "wrong job_stats format found"; }
19048
19049         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19050                 echo "MDS does not yet escape jobid" && return 0
19051         $LCTL set_param jobid_var=TEST205b
19052         env -i TEST205b="has sp" touch $DIR/$tfile.2
19053         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19054                 { do_facet mds1 $LCTL get_param $job_stats;
19055                   error "jobid not escaped"; }
19056 }
19057 run_test 205b "Verify job stats jobid and output format"
19058
19059 # LU-13733
19060 test_205c() {
19061         $LCTL set_param llite.*.stats=0
19062         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19063         $LCTL get_param llite.*.stats
19064         $LCTL get_param llite.*.stats | grep \
19065                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19066                         error "wrong client stats format found"
19067 }
19068 run_test 205c "Verify client stats format"
19069
19070 # LU-1480, LU-1773 and LU-1657
19071 test_206() {
19072         mkdir -p $DIR/$tdir
19073         $LFS setstripe -c -1 $DIR/$tdir
19074 #define OBD_FAIL_LOV_INIT 0x1403
19075         $LCTL set_param fail_loc=0xa0001403
19076         $LCTL set_param fail_val=1
19077         touch $DIR/$tdir/$tfile || true
19078 }
19079 run_test 206 "fail lov_init_raid0() doesn't lbug"
19080
19081 test_207a() {
19082         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19083         local fsz=`stat -c %s $DIR/$tfile`
19084         cancel_lru_locks mdc
19085
19086         # do not return layout in getattr intent
19087 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19088         $LCTL set_param fail_loc=0x170
19089         local sz=`stat -c %s $DIR/$tfile`
19090
19091         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19092
19093         rm -rf $DIR/$tfile
19094 }
19095 run_test 207a "can refresh layout at glimpse"
19096
19097 test_207b() {
19098         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19099         local cksum=`md5sum $DIR/$tfile`
19100         local fsz=`stat -c %s $DIR/$tfile`
19101         cancel_lru_locks mdc
19102         cancel_lru_locks osc
19103
19104         # do not return layout in getattr intent
19105 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19106         $LCTL set_param fail_loc=0x171
19107
19108         # it will refresh layout after the file is opened but before read issues
19109         echo checksum is "$cksum"
19110         echo "$cksum" |md5sum -c --quiet || error "file differs"
19111
19112         rm -rf $DIR/$tfile
19113 }
19114 run_test 207b "can refresh layout at open"
19115
19116 test_208() {
19117         # FIXME: in this test suite, only RD lease is used. This is okay
19118         # for now as only exclusive open is supported. After generic lease
19119         # is done, this test suite should be revised. - Jinshan
19120
19121         remote_mds_nodsh && skip "remote MDS with nodsh"
19122         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19123                 skip "Need MDS version at least 2.4.52"
19124
19125         echo "==== test 1: verify get lease work"
19126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19127
19128         echo "==== test 2: verify lease can be broken by upcoming open"
19129         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19130         local PID=$!
19131         sleep 2
19132
19133         $MULTIOP $DIR/$tfile oO_RDWR:c
19134         kill -USR1 $PID && wait $PID || error "break lease error"
19135
19136         echo "==== test 3: verify lease can't be granted if an open already exists"
19137         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19138         local PID=$!
19139         sleep 2
19140
19141         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19142         kill -USR1 $PID && wait $PID || error "open file error"
19143
19144         echo "==== test 4: lease can sustain over recovery"
19145         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19146         PID=$!
19147         sleep 2
19148
19149         fail mds1
19150
19151         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19152
19153         echo "==== test 5: lease broken can't be regained by replay"
19154         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19155         PID=$!
19156         sleep 2
19157
19158         # open file to break lease and then recovery
19159         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19160         fail mds1
19161
19162         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19163
19164         rm -f $DIR/$tfile
19165 }
19166 run_test 208 "Exclusive open"
19167
19168 test_209() {
19169         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19170                 skip_env "must have disp_stripe"
19171
19172         touch $DIR/$tfile
19173         sync; sleep 5; sync;
19174
19175         echo 3 > /proc/sys/vm/drop_caches
19176         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19177                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19178         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19179
19180         # open/close 500 times
19181         for i in $(seq 500); do
19182                 cat $DIR/$tfile
19183         done
19184
19185         echo 3 > /proc/sys/vm/drop_caches
19186         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19187                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19188         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19189
19190         echo "before: $req_before, after: $req_after"
19191         [ $((req_after - req_before)) -ge 300 ] &&
19192                 error "open/close requests are not freed"
19193         return 0
19194 }
19195 run_test 209 "read-only open/close requests should be freed promptly"
19196
19197 test_210() {
19198         local pid
19199
19200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19201         pid=$!
19202         sleep 1
19203
19204         $LFS getstripe $DIR/$tfile
19205         kill -USR1 $pid
19206         wait $pid || error "multiop failed"
19207
19208         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19209         pid=$!
19210         sleep 1
19211
19212         $LFS getstripe $DIR/$tfile
19213         kill -USR1 $pid
19214         wait $pid || error "multiop failed"
19215 }
19216 run_test 210 "lfs getstripe does not break leases"
19217
19218 test_212() {
19219         size=`date +%s`
19220         size=$((size % 8192 + 1))
19221         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19222         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19223         rm -f $DIR/f212 $DIR/f212.xyz
19224 }
19225 run_test 212 "Sendfile test ============================================"
19226
19227 test_213() {
19228         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19229         cancel_lru_locks osc
19230         lctl set_param fail_loc=0x8000040f
19231         # generate a read lock
19232         cat $DIR/$tfile > /dev/null
19233         # write to the file, it will try to cancel the above read lock.
19234         cat /etc/hosts >> $DIR/$tfile
19235 }
19236 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19237
19238 test_214() { # for bug 20133
19239         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19240         for (( i=0; i < 340; i++ )) ; do
19241                 touch $DIR/$tdir/d214c/a$i
19242         done
19243
19244         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19245         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19246         ls $DIR/d214c || error "ls $DIR/d214c failed"
19247         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19248         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19249 }
19250 run_test 214 "hash-indexed directory test - bug 20133"
19251
19252 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19253 create_lnet_proc_files() {
19254         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19255 }
19256
19257 # counterpart of create_lnet_proc_files
19258 remove_lnet_proc_files() {
19259         rm -f $TMP/lnet_$1.sys
19260 }
19261
19262 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19263 # 3rd arg as regexp for body
19264 check_lnet_proc_stats() {
19265         local l=$(cat "$TMP/lnet_$1" |wc -l)
19266         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19267
19268         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19269 }
19270
19271 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19272 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19273 # optional and can be regexp for 2nd line (lnet.routes case)
19274 check_lnet_proc_entry() {
19275         local blp=2          # blp stands for 'position of 1st line of body'
19276         [ -z "$5" ] || blp=3 # lnet.routes case
19277
19278         local l=$(cat "$TMP/lnet_$1" |wc -l)
19279         # subtracting one from $blp because the body can be empty
19280         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19281
19282         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19283                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19284
19285         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19286                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19287
19288         # bail out if any unexpected line happened
19289         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19290         [ "$?" != 0 ] || error "$2 misformatted"
19291 }
19292
19293 test_215() { # for bugs 18102, 21079, 21517
19294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19295
19296         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19297         local P='[1-9][0-9]*'           # positive numeric
19298         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19299         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19300         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19301         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19302
19303         local L1 # regexp for 1st line
19304         local L2 # regexp for 2nd line (optional)
19305         local BR # regexp for the rest (body)
19306
19307         # lnet.stats should look as 11 space-separated non-negative numerics
19308         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19309         create_lnet_proc_files "stats"
19310         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19311         remove_lnet_proc_files "stats"
19312
19313         # lnet.routes should look like this:
19314         # Routing disabled/enabled
19315         # net hops priority state router
19316         # where net is a string like tcp0, hops > 0, priority >= 0,
19317         # state is up/down,
19318         # router is a string like 192.168.1.1@tcp2
19319         L1="^Routing (disabled|enabled)$"
19320         L2="^net +hops +priority +state +router$"
19321         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19322         create_lnet_proc_files "routes"
19323         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19324         remove_lnet_proc_files "routes"
19325
19326         # lnet.routers should look like this:
19327         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19328         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19329         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19330         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19331         L1="^ref +rtr_ref +alive +router$"
19332         BR="^$P +$P +(up|down) +$NID$"
19333         create_lnet_proc_files "routers"
19334         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19335         remove_lnet_proc_files "routers"
19336
19337         # lnet.peers should look like this:
19338         # nid refs state last max rtr min tx min queue
19339         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19340         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19341         # numeric (0 or >0 or <0), queue >= 0.
19342         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19343         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19344         create_lnet_proc_files "peers"
19345         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19346         remove_lnet_proc_files "peers"
19347
19348         # lnet.buffers  should look like this:
19349         # pages count credits min
19350         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19351         L1="^pages +count +credits +min$"
19352         BR="^ +$N +$N +$I +$I$"
19353         create_lnet_proc_files "buffers"
19354         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19355         remove_lnet_proc_files "buffers"
19356
19357         # lnet.nis should look like this:
19358         # nid status alive refs peer rtr max tx min
19359         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19360         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19361         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19362         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19363         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19364         create_lnet_proc_files "nis"
19365         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19366         remove_lnet_proc_files "nis"
19367
19368         # can we successfully write to lnet.stats?
19369         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19370 }
19371 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19372
19373 test_216() { # bug 20317
19374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19375         remote_ost_nodsh && skip "remote OST with nodsh"
19376
19377         local node
19378         local facets=$(get_facets OST)
19379         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19380
19381         save_lustre_params client "osc.*.contention_seconds" > $p
19382         save_lustre_params $facets \
19383                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19384         save_lustre_params $facets \
19385                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19386         save_lustre_params $facets \
19387                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19388         clear_stats osc.*.osc_stats
19389
19390         # agressive lockless i/o settings
19391         do_nodes $(comma_list $(osts_nodes)) \
19392                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19393                         ldlm.namespaces.filter-*.contended_locks=0 \
19394                         ldlm.namespaces.filter-*.contention_seconds=60"
19395         lctl set_param -n osc.*.contention_seconds=60
19396
19397         $DIRECTIO write $DIR/$tfile 0 10 4096
19398         $CHECKSTAT -s 40960 $DIR/$tfile
19399
19400         # disable lockless i/o
19401         do_nodes $(comma_list $(osts_nodes)) \
19402                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19403                         ldlm.namespaces.filter-*.contended_locks=32 \
19404                         ldlm.namespaces.filter-*.contention_seconds=0"
19405         lctl set_param -n osc.*.contention_seconds=0
19406         clear_stats osc.*.osc_stats
19407
19408         dd if=/dev/zero of=$DIR/$tfile count=0
19409         $CHECKSTAT -s 0 $DIR/$tfile
19410
19411         restore_lustre_params <$p
19412         rm -f $p
19413         rm $DIR/$tfile
19414 }
19415 run_test 216 "check lockless direct write updates file size and kms correctly"
19416
19417 test_217() { # bug 22430
19418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19419
19420         local node
19421         local nid
19422
19423         for node in $(nodes_list); do
19424                 nid=$(host_nids_address $node $NETTYPE)
19425                 if [[ $nid = *-* ]] ; then
19426                         echo "lctl ping $(h2nettype $nid)"
19427                         lctl ping $(h2nettype $nid)
19428                 else
19429                         echo "skipping $node (no hyphen detected)"
19430                 fi
19431         done
19432 }
19433 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19434
19435 test_218() {
19436        # do directio so as not to populate the page cache
19437        log "creating a 10 Mb file"
19438        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19439        log "starting reads"
19440        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19441        log "truncating the file"
19442        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19443        log "killing dd"
19444        kill %+ || true # reads might have finished
19445        echo "wait until dd is finished"
19446        wait
19447        log "removing the temporary file"
19448        rm -rf $DIR/$tfile || error "tmp file removal failed"
19449 }
19450 run_test 218 "parallel read and truncate should not deadlock"
19451
19452 test_219() {
19453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19454
19455         # write one partial page
19456         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19457         # set no grant so vvp_io_commit_write will do sync write
19458         $LCTL set_param fail_loc=0x411
19459         # write a full page at the end of file
19460         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19461
19462         $LCTL set_param fail_loc=0
19463         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19464         $LCTL set_param fail_loc=0x411
19465         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19466
19467         # LU-4201
19468         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19469         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19470 }
19471 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19472
19473 test_220() { #LU-325
19474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19475         remote_ost_nodsh && skip "remote OST with nodsh"
19476         remote_mds_nodsh && skip "remote MDS with nodsh"
19477         remote_mgs_nodsh && skip "remote MGS with nodsh"
19478
19479         local OSTIDX=0
19480
19481         # create on MDT0000 so the last_id and next_id are correct
19482         mkdir_on_mdt0 $DIR/$tdir
19483         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19484         OST=${OST%_UUID}
19485
19486         # on the mdt's osc
19487         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19488         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19489                         osp.$mdtosc_proc1.prealloc_last_id)
19490         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19491                         osp.$mdtosc_proc1.prealloc_next_id)
19492
19493         $LFS df -i
19494
19495         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19496         #define OBD_FAIL_OST_ENOINO              0x229
19497         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19498         create_pool $FSNAME.$TESTNAME || return 1
19499         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19500
19501         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19502
19503         MDSOBJS=$((last_id - next_id))
19504         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19505
19506         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19507         echo "OST still has $count kbytes free"
19508
19509         echo "create $MDSOBJS files @next_id..."
19510         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19511
19512         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19513                         osp.$mdtosc_proc1.prealloc_last_id)
19514         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19515                         osp.$mdtosc_proc1.prealloc_next_id)
19516
19517         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19518         $LFS df -i
19519
19520         echo "cleanup..."
19521
19522         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19523         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19524
19525         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19526                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19527         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19528                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19529         echo "unlink $MDSOBJS files @$next_id..."
19530         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19531 }
19532 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19533
19534 test_221() {
19535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19536
19537         dd if=`which date` of=$MOUNT/date oflag=sync
19538         chmod +x $MOUNT/date
19539
19540         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19541         $LCTL set_param fail_loc=0x80001401
19542
19543         $MOUNT/date > /dev/null
19544         rm -f $MOUNT/date
19545 }
19546 run_test 221 "make sure fault and truncate race to not cause OOM"
19547
19548 test_222a () {
19549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19550
19551         rm -rf $DIR/$tdir
19552         test_mkdir $DIR/$tdir
19553         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19554         createmany -o $DIR/$tdir/$tfile 10
19555         cancel_lru_locks mdc
19556         cancel_lru_locks osc
19557         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19558         $LCTL set_param fail_loc=0x31a
19559         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19560         $LCTL set_param fail_loc=0
19561         rm -r $DIR/$tdir
19562 }
19563 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19564
19565 test_222b () {
19566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19567
19568         rm -rf $DIR/$tdir
19569         test_mkdir $DIR/$tdir
19570         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19571         createmany -o $DIR/$tdir/$tfile 10
19572         cancel_lru_locks mdc
19573         cancel_lru_locks osc
19574         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19575         $LCTL set_param fail_loc=0x31a
19576         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19577         $LCTL set_param fail_loc=0
19578 }
19579 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19580
19581 test_223 () {
19582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19583
19584         rm -rf $DIR/$tdir
19585         test_mkdir $DIR/$tdir
19586         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19587         createmany -o $DIR/$tdir/$tfile 10
19588         cancel_lru_locks mdc
19589         cancel_lru_locks osc
19590         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19591         $LCTL set_param fail_loc=0x31b
19592         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19593         $LCTL set_param fail_loc=0
19594         rm -r $DIR/$tdir
19595 }
19596 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19597
19598 test_224a() { # LU-1039, MRP-303
19599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19600         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19601         $LCTL set_param fail_loc=0x508
19602         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19603         $LCTL set_param fail_loc=0
19604         df $DIR
19605 }
19606 run_test 224a "Don't panic on bulk IO failure"
19607
19608 test_224bd_sub() { # LU-1039, MRP-303
19609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19610         local timeout=$1
19611
19612         shift
19613         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19614
19615         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19616
19617         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19618         cancel_lru_locks osc
19619         set_checksums 0
19620         stack_trap "set_checksums $ORIG_CSUM" EXIT
19621         local at_max_saved=0
19622
19623         # adaptive timeouts may prevent seeing the issue
19624         if at_is_enabled; then
19625                 at_max_saved=$(at_max_get mds)
19626                 at_max_set 0 mds client
19627                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19628         fi
19629
19630         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19631         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19632         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19633
19634         do_facet ost1 $LCTL set_param fail_loc=0
19635         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19636         df $DIR
19637 }
19638
19639 test_224b() {
19640         test_224bd_sub 3 error "dd failed"
19641 }
19642 run_test 224b "Don't panic on bulk IO failure"
19643
19644 test_224c() { # LU-6441
19645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19646         remote_mds_nodsh && skip "remote MDS with nodsh"
19647
19648         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19649         save_writethrough $p
19650         set_cache writethrough on
19651
19652         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19653         local at_max=$($LCTL get_param -n at_max)
19654         local timeout=$($LCTL get_param -n timeout)
19655         local test_at="at_max"
19656         local param_at="$FSNAME.sys.at_max"
19657         local test_timeout="timeout"
19658         local param_timeout="$FSNAME.sys.timeout"
19659
19660         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19661
19662         set_persistent_param_and_check client "$test_at" "$param_at" 0
19663         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19664
19665         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19666         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19667         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19668         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19669         sync
19670         do_facet ost1 "$LCTL set_param fail_loc=0"
19671
19672         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19673         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19674                 $timeout
19675
19676         $LCTL set_param -n $pages_per_rpc
19677         restore_lustre_params < $p
19678         rm -f $p
19679 }
19680 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19681
19682 test_224d() { # LU-11169
19683         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19684 }
19685 run_test 224d "Don't corrupt data on bulk IO timeout"
19686
19687 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19688 test_225a () {
19689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19690         if [ -z ${MDSSURVEY} ]; then
19691                 skip_env "mds-survey not found"
19692         fi
19693         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19694                 skip "Need MDS version at least 2.2.51"
19695
19696         local mds=$(facet_host $SINGLEMDS)
19697         local target=$(do_nodes $mds 'lctl dl' |
19698                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19699
19700         local cmd1="file_count=1000 thrhi=4"
19701         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19702         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19703         local cmd="$cmd1 $cmd2 $cmd3"
19704
19705         rm -f ${TMP}/mds_survey*
19706         echo + $cmd
19707         eval $cmd || error "mds-survey with zero-stripe failed"
19708         cat ${TMP}/mds_survey*
19709         rm -f ${TMP}/mds_survey*
19710 }
19711 run_test 225a "Metadata survey sanity with zero-stripe"
19712
19713 test_225b () {
19714         if [ -z ${MDSSURVEY} ]; then
19715                 skip_env "mds-survey not found"
19716         fi
19717         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19718                 skip "Need MDS version at least 2.2.51"
19719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19720         remote_mds_nodsh && skip "remote MDS with nodsh"
19721         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19722                 skip_env "Need to mount OST to test"
19723         fi
19724
19725         local mds=$(facet_host $SINGLEMDS)
19726         local target=$(do_nodes $mds 'lctl dl' |
19727                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19728
19729         local cmd1="file_count=1000 thrhi=4"
19730         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19731         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19732         local cmd="$cmd1 $cmd2 $cmd3"
19733
19734         rm -f ${TMP}/mds_survey*
19735         echo + $cmd
19736         eval $cmd || error "mds-survey with stripe_count failed"
19737         cat ${TMP}/mds_survey*
19738         rm -f ${TMP}/mds_survey*
19739 }
19740 run_test 225b "Metadata survey sanity with stripe_count = 1"
19741
19742 mcreate_path2fid () {
19743         local mode=$1
19744         local major=$2
19745         local minor=$3
19746         local name=$4
19747         local desc=$5
19748         local path=$DIR/$tdir/$name
19749         local fid
19750         local rc
19751         local fid_path
19752
19753         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19754                 error "cannot create $desc"
19755
19756         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19757         rc=$?
19758         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19759
19760         fid_path=$($LFS fid2path $MOUNT $fid)
19761         rc=$?
19762         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19763
19764         [ "$path" == "$fid_path" ] ||
19765                 error "fid2path returned $fid_path, expected $path"
19766
19767         echo "pass with $path and $fid"
19768 }
19769
19770 test_226a () {
19771         rm -rf $DIR/$tdir
19772         mkdir -p $DIR/$tdir
19773
19774         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19775         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19776         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19777         mcreate_path2fid 0040666 0 0 dir "directory"
19778         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19779         mcreate_path2fid 0100666 0 0 file "regular file"
19780         mcreate_path2fid 0120666 0 0 link "symbolic link"
19781         mcreate_path2fid 0140666 0 0 sock "socket"
19782 }
19783 run_test 226a "call path2fid and fid2path on files of all type"
19784
19785 test_226b () {
19786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19787
19788         local MDTIDX=1
19789
19790         rm -rf $DIR/$tdir
19791         mkdir -p $DIR/$tdir
19792         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19793                 error "create remote directory failed"
19794         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19795         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19796                                 "character special file (null)"
19797         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19798                                 "character special file (no device)"
19799         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19800         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19801                                 "block special file (loop)"
19802         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19803         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19804         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19805 }
19806 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19807
19808 test_226c () {
19809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19810         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19811                 skip "Need MDS version at least 2.13.55"
19812
19813         local submnt=/mnt/submnt
19814         local srcfile=/etc/passwd
19815         local dstfile=$submnt/passwd
19816         local path
19817         local fid
19818
19819         rm -rf $DIR/$tdir
19820         rm -rf $submnt
19821         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19822                 error "create remote directory failed"
19823         mkdir -p $submnt || error "create $submnt failed"
19824         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19825                 error "mount $submnt failed"
19826         stack_trap "umount $submnt" EXIT
19827
19828         cp $srcfile $dstfile
19829         fid=$($LFS path2fid $dstfile)
19830         path=$($LFS fid2path $submnt "$fid")
19831         [ "$path" = "$dstfile" ] ||
19832                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19833 }
19834 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19835
19836 # LU-1299 Executing or running ldd on a truncated executable does not
19837 # cause an out-of-memory condition.
19838 test_227() {
19839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19840         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19841
19842         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19843         chmod +x $MOUNT/date
19844
19845         $MOUNT/date > /dev/null
19846         ldd $MOUNT/date > /dev/null
19847         rm -f $MOUNT/date
19848 }
19849 run_test 227 "running truncated executable does not cause OOM"
19850
19851 # LU-1512 try to reuse idle OI blocks
19852 test_228a() {
19853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19854         remote_mds_nodsh && skip "remote MDS with nodsh"
19855         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19856
19857         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19858         local myDIR=$DIR/$tdir
19859
19860         mkdir -p $myDIR
19861         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19862         $LCTL set_param fail_loc=0x80001002
19863         createmany -o $myDIR/t- 10000
19864         $LCTL set_param fail_loc=0
19865         # The guard is current the largest FID holder
19866         touch $myDIR/guard
19867         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19868                     tr -d '[')
19869         local IDX=$(($SEQ % 64))
19870
19871         do_facet $SINGLEMDS sync
19872         # Make sure journal flushed.
19873         sleep 6
19874         local blk1=$(do_facet $SINGLEMDS \
19875                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19876                      grep Blockcount | awk '{print $4}')
19877
19878         # Remove old files, some OI blocks will become idle.
19879         unlinkmany $myDIR/t- 10000
19880         # Create new files, idle OI blocks should be reused.
19881         createmany -o $myDIR/t- 2000
19882         do_facet $SINGLEMDS sync
19883         # Make sure journal flushed.
19884         sleep 6
19885         local blk2=$(do_facet $SINGLEMDS \
19886                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19887                      grep Blockcount | awk '{print $4}')
19888
19889         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19890 }
19891 run_test 228a "try to reuse idle OI blocks"
19892
19893 test_228b() {
19894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19895         remote_mds_nodsh && skip "remote MDS with nodsh"
19896         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19897
19898         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19899         local myDIR=$DIR/$tdir
19900
19901         mkdir -p $myDIR
19902         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19903         $LCTL set_param fail_loc=0x80001002
19904         createmany -o $myDIR/t- 10000
19905         $LCTL set_param fail_loc=0
19906         # The guard is current the largest FID holder
19907         touch $myDIR/guard
19908         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19909                     tr -d '[')
19910         local IDX=$(($SEQ % 64))
19911
19912         do_facet $SINGLEMDS sync
19913         # Make sure journal flushed.
19914         sleep 6
19915         local blk1=$(do_facet $SINGLEMDS \
19916                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19917                      grep Blockcount | awk '{print $4}')
19918
19919         # Remove old files, some OI blocks will become idle.
19920         unlinkmany $myDIR/t- 10000
19921
19922         # stop the MDT
19923         stop $SINGLEMDS || error "Fail to stop MDT."
19924         # remount the MDT
19925         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19926                 error "Fail to start MDT."
19927
19928         df $MOUNT || error "Fail to df."
19929         # Create new files, idle OI blocks should be reused.
19930         createmany -o $myDIR/t- 2000
19931         do_facet $SINGLEMDS sync
19932         # Make sure journal flushed.
19933         sleep 6
19934         local blk2=$(do_facet $SINGLEMDS \
19935                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19936                      grep Blockcount | awk '{print $4}')
19937
19938         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19939 }
19940 run_test 228b "idle OI blocks can be reused after MDT restart"
19941
19942 #LU-1881
19943 test_228c() {
19944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19945         remote_mds_nodsh && skip "remote MDS with nodsh"
19946         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19947
19948         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19949         local myDIR=$DIR/$tdir
19950
19951         mkdir -p $myDIR
19952         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19953         $LCTL set_param fail_loc=0x80001002
19954         # 20000 files can guarantee there are index nodes in the OI file
19955         createmany -o $myDIR/t- 20000
19956         $LCTL set_param fail_loc=0
19957         # The guard is current the largest FID holder
19958         touch $myDIR/guard
19959         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19960                     tr -d '[')
19961         local IDX=$(($SEQ % 64))
19962
19963         do_facet $SINGLEMDS sync
19964         # Make sure journal flushed.
19965         sleep 6
19966         local blk1=$(do_facet $SINGLEMDS \
19967                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19968                      grep Blockcount | awk '{print $4}')
19969
19970         # Remove old files, some OI blocks will become idle.
19971         unlinkmany $myDIR/t- 20000
19972         rm -f $myDIR/guard
19973         # The OI file should become empty now
19974
19975         # Create new files, idle OI blocks should be reused.
19976         createmany -o $myDIR/t- 2000
19977         do_facet $SINGLEMDS sync
19978         # Make sure journal flushed.
19979         sleep 6
19980         local blk2=$(do_facet $SINGLEMDS \
19981                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19982                      grep Blockcount | awk '{print $4}')
19983
19984         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19985 }
19986 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19987
19988 test_229() { # LU-2482, LU-3448
19989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19990         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19991         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19992                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19993
19994         rm -f $DIR/$tfile
19995
19996         # Create a file with a released layout and stripe count 2.
19997         $MULTIOP $DIR/$tfile H2c ||
19998                 error "failed to create file with released layout"
19999
20000         $LFS getstripe -v $DIR/$tfile
20001
20002         local pattern=$($LFS getstripe -L $DIR/$tfile)
20003         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20004
20005         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20006                 error "getstripe"
20007         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20008         stat $DIR/$tfile || error "failed to stat released file"
20009
20010         chown $RUNAS_ID $DIR/$tfile ||
20011                 error "chown $RUNAS_ID $DIR/$tfile failed"
20012
20013         chgrp $RUNAS_ID $DIR/$tfile ||
20014                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20015
20016         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20017         rm $DIR/$tfile || error "failed to remove released file"
20018 }
20019 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20020
20021 test_230a() {
20022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20025                 skip "Need MDS version at least 2.11.52"
20026
20027         local MDTIDX=1
20028
20029         test_mkdir $DIR/$tdir
20030         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20031         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20032         [ $mdt_idx -ne 0 ] &&
20033                 error "create local directory on wrong MDT $mdt_idx"
20034
20035         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20036                         error "create remote directory failed"
20037         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20038         [ $mdt_idx -ne $MDTIDX ] &&
20039                 error "create remote directory on wrong MDT $mdt_idx"
20040
20041         createmany -o $DIR/$tdir/test_230/t- 10 ||
20042                 error "create files on remote directory failed"
20043         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20044         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20045         rm -r $DIR/$tdir || error "unlink remote directory failed"
20046 }
20047 run_test 230a "Create remote directory and files under the remote directory"
20048
20049 test_230b() {
20050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20052         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20053                 skip "Need MDS version at least 2.11.52"
20054
20055         local MDTIDX=1
20056         local mdt_index
20057         local i
20058         local file
20059         local pid
20060         local stripe_count
20061         local migrate_dir=$DIR/$tdir/migrate_dir
20062         local other_dir=$DIR/$tdir/other_dir
20063
20064         test_mkdir $DIR/$tdir
20065         test_mkdir -i0 -c1 $migrate_dir
20066         test_mkdir -i0 -c1 $other_dir
20067         for ((i=0; i<10; i++)); do
20068                 mkdir -p $migrate_dir/dir_${i}
20069                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20070                         error "create files under remote dir failed $i"
20071         done
20072
20073         cp /etc/passwd $migrate_dir/$tfile
20074         cp /etc/passwd $other_dir/$tfile
20075         chattr +SAD $migrate_dir
20076         chattr +SAD $migrate_dir/$tfile
20077
20078         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20079         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20080         local old_dir_mode=$(stat -c%f $migrate_dir)
20081         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20082
20083         mkdir -p $migrate_dir/dir_default_stripe2
20084         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20085         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20086
20087         mkdir -p $other_dir
20088         ln $migrate_dir/$tfile $other_dir/luna
20089         ln $migrate_dir/$tfile $migrate_dir/sofia
20090         ln $other_dir/$tfile $migrate_dir/david
20091         ln -s $migrate_dir/$tfile $other_dir/zachary
20092         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20093         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20094
20095         local len
20096         local lnktgt
20097
20098         # inline symlink
20099         for len in 58 59 60; do
20100                 lnktgt=$(str_repeat 'l' $len)
20101                 touch $migrate_dir/$lnktgt
20102                 ln -s $lnktgt $migrate_dir/${len}char_ln
20103         done
20104
20105         # PATH_MAX
20106         for len in 4094 4095; do
20107                 lnktgt=$(str_repeat 'l' $len)
20108                 ln -s $lnktgt $migrate_dir/${len}char_ln
20109         done
20110
20111         # NAME_MAX
20112         for len in 254 255; do
20113                 touch $migrate_dir/$(str_repeat 'l' $len)
20114         done
20115
20116         $LFS migrate -m $MDTIDX $migrate_dir ||
20117                 error "fails on migrating remote dir to MDT1"
20118
20119         echo "migratate to MDT1, then checking.."
20120         for ((i = 0; i < 10; i++)); do
20121                 for file in $(find $migrate_dir/dir_${i}); do
20122                         mdt_index=$($LFS getstripe -m $file)
20123                         # broken symlink getstripe will fail
20124                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20125                                 error "$file is not on MDT${MDTIDX}"
20126                 done
20127         done
20128
20129         # the multiple link file should still in MDT0
20130         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20131         [ $mdt_index == 0 ] ||
20132                 error "$file is not on MDT${MDTIDX}"
20133
20134         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20135         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20136                 error " expect $old_dir_flag get $new_dir_flag"
20137
20138         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20139         [ "$old_file_flag" = "$new_file_flag" ] ||
20140                 error " expect $old_file_flag get $new_file_flag"
20141
20142         local new_dir_mode=$(stat -c%f $migrate_dir)
20143         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20144                 error "expect mode $old_dir_mode get $new_dir_mode"
20145
20146         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20147         [ "$old_file_mode" = "$new_file_mode" ] ||
20148                 error "expect mode $old_file_mode get $new_file_mode"
20149
20150         diff /etc/passwd $migrate_dir/$tfile ||
20151                 error "$tfile different after migration"
20152
20153         diff /etc/passwd $other_dir/luna ||
20154                 error "luna different after migration"
20155
20156         diff /etc/passwd $migrate_dir/sofia ||
20157                 error "sofia different after migration"
20158
20159         diff /etc/passwd $migrate_dir/david ||
20160                 error "david different after migration"
20161
20162         diff /etc/passwd $other_dir/zachary ||
20163                 error "zachary different after migration"
20164
20165         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20166                 error "${tfile}_ln different after migration"
20167
20168         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20169                 error "${tfile}_ln_other different after migration"
20170
20171         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20172         [ $stripe_count = 2 ] ||
20173                 error "dir strpe_count $d != 2 after migration."
20174
20175         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20176         [ $stripe_count = 2 ] ||
20177                 error "file strpe_count $d != 2 after migration."
20178
20179         #migrate back to MDT0
20180         MDTIDX=0
20181
20182         $LFS migrate -m $MDTIDX $migrate_dir ||
20183                 error "fails on migrating remote dir to MDT0"
20184
20185         echo "migrate back to MDT0, checking.."
20186         for file in $(find $migrate_dir); do
20187                 mdt_index=$($LFS getstripe -m $file)
20188                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20189                         error "$file is not on MDT${MDTIDX}"
20190         done
20191
20192         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20193         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20194                 error " expect $old_dir_flag get $new_dir_flag"
20195
20196         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20197         [ "$old_file_flag" = "$new_file_flag" ] ||
20198                 error " expect $old_file_flag get $new_file_flag"
20199
20200         local new_dir_mode=$(stat -c%f $migrate_dir)
20201         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20202                 error "expect mode $old_dir_mode get $new_dir_mode"
20203
20204         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20205         [ "$old_file_mode" = "$new_file_mode" ] ||
20206                 error "expect mode $old_file_mode get $new_file_mode"
20207
20208         diff /etc/passwd ${migrate_dir}/$tfile ||
20209                 error "$tfile different after migration"
20210
20211         diff /etc/passwd ${other_dir}/luna ||
20212                 error "luna different after migration"
20213
20214         diff /etc/passwd ${migrate_dir}/sofia ||
20215                 error "sofia different after migration"
20216
20217         diff /etc/passwd ${other_dir}/zachary ||
20218                 error "zachary different after migration"
20219
20220         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20221                 error "${tfile}_ln different after migration"
20222
20223         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20224                 error "${tfile}_ln_other different after migration"
20225
20226         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20227         [ $stripe_count = 2 ] ||
20228                 error "dir strpe_count $d != 2 after migration."
20229
20230         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20231         [ $stripe_count = 2 ] ||
20232                 error "file strpe_count $d != 2 after migration."
20233
20234         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20235 }
20236 run_test 230b "migrate directory"
20237
20238 test_230c() {
20239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20241         remote_mds_nodsh && skip "remote MDS with nodsh"
20242         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20243                 skip "Need MDS version at least 2.11.52"
20244
20245         local MDTIDX=1
20246         local total=3
20247         local mdt_index
20248         local file
20249         local migrate_dir=$DIR/$tdir/migrate_dir
20250
20251         #If migrating directory fails in the middle, all entries of
20252         #the directory is still accessiable.
20253         test_mkdir $DIR/$tdir
20254         test_mkdir -i0 -c1 $migrate_dir
20255         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20256         stat $migrate_dir
20257         createmany -o $migrate_dir/f $total ||
20258                 error "create files under ${migrate_dir} failed"
20259
20260         # fail after migrating top dir, and this will fail only once, so the
20261         # first sub file migration will fail (currently f3), others succeed.
20262         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20263         do_facet mds1 lctl set_param fail_loc=0x1801
20264         local t=$(ls $migrate_dir | wc -l)
20265         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20266                 error "migrate should fail"
20267         local u=$(ls $migrate_dir | wc -l)
20268         [ "$u" == "$t" ] || error "$u != $t during migration"
20269
20270         # add new dir/file should succeed
20271         mkdir $migrate_dir/dir ||
20272                 error "mkdir failed under migrating directory"
20273         touch $migrate_dir/file ||
20274                 error "create file failed under migrating directory"
20275
20276         # add file with existing name should fail
20277         for file in $migrate_dir/f*; do
20278                 stat $file > /dev/null || error "stat $file failed"
20279                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20280                         error "open(O_CREAT|O_EXCL) $file should fail"
20281                 $MULTIOP $file m && error "create $file should fail"
20282                 touch $DIR/$tdir/remote_dir/$tfile ||
20283                         error "touch $tfile failed"
20284                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20285                         error "link $file should fail"
20286                 mdt_index=$($LFS getstripe -m $file)
20287                 if [ $mdt_index == 0 ]; then
20288                         # file failed to migrate is not allowed to rename to
20289                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20290                                 error "rename to $file should fail"
20291                 else
20292                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20293                                 error "rename to $file failed"
20294                 fi
20295                 echo hello >> $file || error "write $file failed"
20296         done
20297
20298         # resume migration with different options should fail
20299         $LFS migrate -m 0 $migrate_dir &&
20300                 error "migrate -m 0 $migrate_dir should fail"
20301
20302         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20303                 error "migrate -c 2 $migrate_dir should fail"
20304
20305         # resume migration should succeed
20306         $LFS migrate -m $MDTIDX $migrate_dir ||
20307                 error "migrate $migrate_dir failed"
20308
20309         echo "Finish migration, then checking.."
20310         for file in $(find $migrate_dir); do
20311                 mdt_index=$($LFS getstripe -m $file)
20312                 [ $mdt_index == $MDTIDX ] ||
20313                         error "$file is not on MDT${MDTIDX}"
20314         done
20315
20316         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20317 }
20318 run_test 230c "check directory accessiblity if migration failed"
20319
20320 test_230d() {
20321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20323         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20324                 skip "Need MDS version at least 2.11.52"
20325         # LU-11235
20326         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20327
20328         local migrate_dir=$DIR/$tdir/migrate_dir
20329         local old_index
20330         local new_index
20331         local old_count
20332         local new_count
20333         local new_hash
20334         local mdt_index
20335         local i
20336         local j
20337
20338         old_index=$((RANDOM % MDSCOUNT))
20339         old_count=$((MDSCOUNT - old_index))
20340         new_index=$((RANDOM % MDSCOUNT))
20341         new_count=$((MDSCOUNT - new_index))
20342         new_hash=1 # for all_char
20343
20344         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20345         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20346
20347         test_mkdir $DIR/$tdir
20348         test_mkdir -i $old_index -c $old_count $migrate_dir
20349
20350         for ((i=0; i<100; i++)); do
20351                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20352                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20353                         error "create files under remote dir failed $i"
20354         done
20355
20356         echo -n "Migrate from MDT$old_index "
20357         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20358         echo -n "to MDT$new_index"
20359         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20360         echo
20361
20362         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20363         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20364                 error "migrate remote dir error"
20365
20366         echo "Finish migration, then checking.."
20367         for file in $(find $migrate_dir -maxdepth 1); do
20368                 mdt_index=$($LFS getstripe -m $file)
20369                 if [ $mdt_index -lt $new_index ] ||
20370                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20371                         error "$file is on MDT$mdt_index"
20372                 fi
20373         done
20374
20375         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20376 }
20377 run_test 230d "check migrate big directory"
20378
20379 test_230e() {
20380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20382         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20383                 skip "Need MDS version at least 2.11.52"
20384
20385         local i
20386         local j
20387         local a_fid
20388         local b_fid
20389
20390         mkdir_on_mdt0 $DIR/$tdir
20391         mkdir $DIR/$tdir/migrate_dir
20392         mkdir $DIR/$tdir/other_dir
20393         touch $DIR/$tdir/migrate_dir/a
20394         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20395         ls $DIR/$tdir/other_dir
20396
20397         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20398                 error "migrate dir fails"
20399
20400         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20401         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20402
20403         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20404         [ $mdt_index == 0 ] || error "a is not on MDT0"
20405
20406         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20407                 error "migrate dir fails"
20408
20409         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20410         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20411
20412         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20413         [ $mdt_index == 1 ] || error "a is not on MDT1"
20414
20415         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20416         [ $mdt_index == 1 ] || error "b is not on MDT1"
20417
20418         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20419         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20420
20421         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20422
20423         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20424 }
20425 run_test 230e "migrate mulitple local link files"
20426
20427 test_230f() {
20428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20430         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20431                 skip "Need MDS version at least 2.11.52"
20432
20433         local a_fid
20434         local ln_fid
20435
20436         mkdir -p $DIR/$tdir
20437         mkdir $DIR/$tdir/migrate_dir
20438         $LFS mkdir -i1 $DIR/$tdir/other_dir
20439         touch $DIR/$tdir/migrate_dir/a
20440         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20441         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20442         ls $DIR/$tdir/other_dir
20443
20444         # a should be migrated to MDT1, since no other links on MDT0
20445         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20446                 error "#1 migrate dir fails"
20447         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20448         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20449         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20450         [ $mdt_index == 1 ] || error "a is not on MDT1"
20451
20452         # a should stay on MDT1, because it is a mulitple link file
20453         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20454                 error "#2 migrate dir fails"
20455         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20456         [ $mdt_index == 1 ] || error "a is not on MDT1"
20457
20458         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20459                 error "#3 migrate dir fails"
20460
20461         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20462         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20463         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20464
20465         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20466         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20467
20468         # a should be migrated to MDT0, since no other links on MDT1
20469         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20470                 error "#4 migrate dir fails"
20471         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20472         [ $mdt_index == 0 ] || error "a is not on MDT0"
20473
20474         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20475 }
20476 run_test 230f "migrate mulitple remote link files"
20477
20478 test_230g() {
20479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20481         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20482                 skip "Need MDS version at least 2.11.52"
20483
20484         mkdir -p $DIR/$tdir/migrate_dir
20485
20486         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20487                 error "migrating dir to non-exist MDT succeeds"
20488         true
20489 }
20490 run_test 230g "migrate dir to non-exist MDT"
20491
20492 test_230h() {
20493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20495         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20496                 skip "Need MDS version at least 2.11.52"
20497
20498         local mdt_index
20499
20500         mkdir -p $DIR/$tdir/migrate_dir
20501
20502         $LFS migrate -m1 $DIR &&
20503                 error "migrating mountpoint1 should fail"
20504
20505         $LFS migrate -m1 $DIR/$tdir/.. &&
20506                 error "migrating mountpoint2 should fail"
20507
20508         # same as mv
20509         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20510                 error "migrating $tdir/migrate_dir/.. should fail"
20511
20512         true
20513 }
20514 run_test 230h "migrate .. and root"
20515
20516 test_230i() {
20517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20519         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20520                 skip "Need MDS version at least 2.11.52"
20521
20522         mkdir -p $DIR/$tdir/migrate_dir
20523
20524         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20525                 error "migration fails with a tailing slash"
20526
20527         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20528                 error "migration fails with two tailing slashes"
20529 }
20530 run_test 230i "lfs migrate -m tolerates trailing slashes"
20531
20532 test_230j() {
20533         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20534         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20535                 skip "Need MDS version at least 2.11.52"
20536
20537         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20538         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20539                 error "create $tfile failed"
20540         cat /etc/passwd > $DIR/$tdir/$tfile
20541
20542         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20543
20544         cmp /etc/passwd $DIR/$tdir/$tfile ||
20545                 error "DoM file mismatch after migration"
20546 }
20547 run_test 230j "DoM file data not changed after dir migration"
20548
20549 test_230k() {
20550         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20551         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20552                 skip "Need MDS version at least 2.11.56"
20553
20554         local total=20
20555         local files_on_starting_mdt=0
20556
20557         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20558         $LFS getdirstripe $DIR/$tdir
20559         for i in $(seq $total); do
20560                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20561                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20562                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20563         done
20564
20565         echo "$files_on_starting_mdt files on MDT0"
20566
20567         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20568         $LFS getdirstripe $DIR/$tdir
20569
20570         files_on_starting_mdt=0
20571         for i in $(seq $total); do
20572                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20573                         error "file $tfile.$i mismatch after migration"
20574                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20575                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20576         done
20577
20578         echo "$files_on_starting_mdt files on MDT1 after migration"
20579         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20580
20581         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20582         $LFS getdirstripe $DIR/$tdir
20583
20584         files_on_starting_mdt=0
20585         for i in $(seq $total); do
20586                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20587                         error "file $tfile.$i mismatch after 2nd migration"
20588                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20589                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20590         done
20591
20592         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20593         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20594
20595         true
20596 }
20597 run_test 230k "file data not changed after dir migration"
20598
20599 test_230l() {
20600         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20601         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20602                 skip "Need MDS version at least 2.11.56"
20603
20604         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20605         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20606                 error "create files under remote dir failed $i"
20607         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20608 }
20609 run_test 230l "readdir between MDTs won't crash"
20610
20611 test_230m() {
20612         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20613         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20614                 skip "Need MDS version at least 2.11.56"
20615
20616         local MDTIDX=1
20617         local mig_dir=$DIR/$tdir/migrate_dir
20618         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20619         local shortstr="b"
20620         local val
20621
20622         echo "Creating files and dirs with xattrs"
20623         test_mkdir $DIR/$tdir
20624         test_mkdir -i0 -c1 $mig_dir
20625         mkdir $mig_dir/dir
20626         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20627                 error "cannot set xattr attr1 on dir"
20628         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20629                 error "cannot set xattr attr2 on dir"
20630         touch $mig_dir/dir/f0
20631         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20632                 error "cannot set xattr attr1 on file"
20633         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20634                 error "cannot set xattr attr2 on file"
20635         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20636         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20637         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20638         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20639         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20640         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20641         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20642         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20643         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20644
20645         echo "Migrating to MDT1"
20646         $LFS migrate -m $MDTIDX $mig_dir ||
20647                 error "fails on migrating dir to MDT1"
20648
20649         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20650         echo "Checking xattrs"
20651         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20652         [ "$val" = $longstr ] ||
20653                 error "expecting xattr1 $longstr on dir, found $val"
20654         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20655         [ "$val" = $shortstr ] ||
20656                 error "expecting xattr2 $shortstr on dir, found $val"
20657         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20658         [ "$val" = $longstr ] ||
20659                 error "expecting xattr1 $longstr on file, found $val"
20660         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20661         [ "$val" = $shortstr ] ||
20662                 error "expecting xattr2 $shortstr on file, found $val"
20663 }
20664 run_test 230m "xattrs not changed after dir migration"
20665
20666 test_230n() {
20667         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20668         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20669                 skip "Need MDS version at least 2.13.53"
20670
20671         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20672         cat /etc/hosts > $DIR/$tdir/$tfile
20673         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20674         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20675
20676         cmp /etc/hosts $DIR/$tdir/$tfile ||
20677                 error "File data mismatch after migration"
20678 }
20679 run_test 230n "Dir migration with mirrored file"
20680
20681 test_230o() {
20682         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20683         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20684                 skip "Need MDS version at least 2.13.52"
20685
20686         local mdts=$(comma_list $(mdts_nodes))
20687         local timeout=100
20688         local restripe_status
20689         local delta
20690         local i
20691
20692         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20693
20694         # in case "crush" hash type is not set
20695         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20696
20697         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20698                            mdt.*MDT0000.enable_dir_restripe)
20699         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20700         stack_trap "do_nodes $mdts $LCTL set_param \
20701                     mdt.*.enable_dir_restripe=$restripe_status"
20702
20703         mkdir $DIR/$tdir
20704         createmany -m $DIR/$tdir/f 100 ||
20705                 error "create files under remote dir failed $i"
20706         createmany -d $DIR/$tdir/d 100 ||
20707                 error "create dirs under remote dir failed $i"
20708
20709         for i in $(seq 2 $MDSCOUNT); do
20710                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20711                 $LFS setdirstripe -c $i $DIR/$tdir ||
20712                         error "split -c $i $tdir failed"
20713                 wait_update $HOSTNAME \
20714                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20715                         error "dir split not finished"
20716                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20717                         awk '/migrate/ {sum += $2} END { print sum }')
20718                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20719                 # delta is around total_files/stripe_count
20720                 (( $delta < 200 / (i - 1) + 4 )) ||
20721                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20722         done
20723 }
20724 run_test 230o "dir split"
20725
20726 test_230p() {
20727         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20728         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20729                 skip "Need MDS version at least 2.13.52"
20730
20731         local mdts=$(comma_list $(mdts_nodes))
20732         local timeout=100
20733         local restripe_status
20734         local delta
20735         local c
20736
20737         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20738
20739         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20740
20741         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20742                            mdt.*MDT0000.enable_dir_restripe)
20743         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20744         stack_trap "do_nodes $mdts $LCTL set_param \
20745                     mdt.*.enable_dir_restripe=$restripe_status"
20746
20747         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20748         createmany -m $DIR/$tdir/f 100 ||
20749                 error "create files under remote dir failed"
20750         createmany -d $DIR/$tdir/d 100 ||
20751                 error "create dirs under remote dir failed"
20752
20753         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20754                 local mdt_hash="crush"
20755
20756                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20757                 $LFS setdirstripe -c $c $DIR/$tdir ||
20758                         error "split -c $c $tdir failed"
20759                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20760                         mdt_hash="$mdt_hash,fixed"
20761                 elif [ $c -eq 1 ]; then
20762                         mdt_hash="none"
20763                 fi
20764                 wait_update $HOSTNAME \
20765                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20766                         error "dir merge not finished"
20767                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20768                         awk '/migrate/ {sum += $2} END { print sum }')
20769                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20770                 # delta is around total_files/stripe_count
20771                 (( delta < 200 / c + 4 )) ||
20772                         error "$delta files migrated >= $((200 / c + 4))"
20773         done
20774 }
20775 run_test 230p "dir merge"
20776
20777 test_230q() {
20778         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20779         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20780                 skip "Need MDS version at least 2.13.52"
20781
20782         local mdts=$(comma_list $(mdts_nodes))
20783         local saved_threshold=$(do_facet mds1 \
20784                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20785         local saved_delta=$(do_facet mds1 \
20786                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20787         local threshold=100
20788         local delta=2
20789         local total=0
20790         local stripe_count=0
20791         local stripe_index
20792         local nr_files
20793         local create
20794
20795         # test with fewer files on ZFS
20796         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20797
20798         stack_trap "do_nodes $mdts $LCTL set_param \
20799                     mdt.*.dir_split_count=$saved_threshold"
20800         stack_trap "do_nodes $mdts $LCTL set_param \
20801                     mdt.*.dir_split_delta=$saved_delta"
20802         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20803         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20804         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20805         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20806         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20807         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20808
20809         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20810         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20811
20812         create=$((threshold * 3 / 2))
20813         while [ $stripe_count -lt $MDSCOUNT ]; do
20814                 createmany -m $DIR/$tdir/f $total $create ||
20815                         error "create sub files failed"
20816                 stat $DIR/$tdir > /dev/null
20817                 total=$((total + create))
20818                 stripe_count=$((stripe_count + delta))
20819                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20820
20821                 wait_update $HOSTNAME \
20822                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20823                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20824
20825                 wait_update $HOSTNAME \
20826                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20827                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20828
20829                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20830                 echo "$nr_files/$total files on MDT$stripe_index after split"
20831                 # allow 10% margin of imbalance with crush hash
20832                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20833                         error "$nr_files files on MDT$stripe_index after split"
20834
20835                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20836                 [ $nr_files -eq $total ] ||
20837                         error "total sub files $nr_files != $total"
20838         done
20839
20840         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20841
20842         echo "fixed layout directory won't auto split"
20843         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20844         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20845                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20846         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20847                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20848 }
20849 run_test 230q "dir auto split"
20850
20851 test_230r() {
20852         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20853         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20854         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20855                 skip "Need MDS version at least 2.13.54"
20856
20857         # maximum amount of local locks:
20858         # parent striped dir - 2 locks
20859         # new stripe in parent to migrate to - 1 lock
20860         # source and target - 2 locks
20861         # Total 5 locks for regular file
20862         mkdir -p $DIR/$tdir
20863         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20864         touch $DIR/$tdir/dir1/eee
20865
20866         # create 4 hardlink for 4 more locks
20867         # Total: 9 locks > RS_MAX_LOCKS (8)
20868         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20869         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20870         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20871         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20872         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20873         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20874         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20875         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20876
20877         cancel_lru_locks mdc
20878
20879         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20880                 error "migrate dir fails"
20881
20882         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20883 }
20884 run_test 230r "migrate with too many local locks"
20885
20886 test_230s() {
20887         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20888                 skip "Need MDS version at least 2.14.52"
20889
20890         local mdts=$(comma_list $(mdts_nodes))
20891         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20892                                 mdt.*MDT0000.enable_dir_restripe)
20893
20894         stack_trap "do_nodes $mdts $LCTL set_param \
20895                     mdt.*.enable_dir_restripe=$restripe_status"
20896
20897         local st
20898         for st in 0 1; do
20899                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20900                 test_mkdir $DIR/$tdir
20901                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20902                         error "$LFS mkdir should return EEXIST if target exists"
20903                 rmdir $DIR/$tdir
20904         done
20905 }
20906 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20907
20908 test_230t()
20909 {
20910         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20911         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20912                 skip "Need MDS version at least 2.14.50"
20913
20914         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20915         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20916         $LFS project -p 1 -s $DIR/$tdir ||
20917                 error "set $tdir project id failed"
20918         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20919                 error "set subdir project id failed"
20920         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20921 }
20922 run_test 230t "migrate directory with project ID set"
20923
20924 test_230u()
20925 {
20926         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20927         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20928                 skip "Need MDS version at least 2.14.53"
20929
20930         local count
20931
20932         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20933         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20934         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20935         for i in $(seq 0 $((MDSCOUNT - 1))); do
20936                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20937                 echo "$count dirs migrated to MDT$i"
20938         done
20939         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20940         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20941 }
20942 run_test 230u "migrate directory by QOS"
20943
20944 test_230v()
20945 {
20946         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20947         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20948                 skip "Need MDS version at least 2.14.53"
20949
20950         local count
20951
20952         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20953         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20954         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20955         for i in $(seq 0 $((MDSCOUNT - 1))); do
20956                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20957                 echo "$count subdirs migrated to MDT$i"
20958                 (( i == 3 )) && (( count > 0 )) &&
20959                         error "subdir shouldn't be migrated to MDT3"
20960         done
20961         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20962         (( count == 3 )) || error "dirs migrated to $count MDTs"
20963 }
20964 run_test 230v "subdir migrated to the MDT where its parent is located"
20965
20966 test_230w() {
20967         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20968         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
20969                 skip "Need MDS version at least 2.15.0"
20970
20971         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20972         createmany -o $DIR/$tdir/f 10 || error "create files failed"
20973         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
20974
20975         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20976                 error "migrate failed"
20977
20978         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20979                 error "$tdir stripe count mismatch"
20980
20981         for i in $(seq 0 9); do
20982                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
20983                         error "d$i is striped"
20984         done
20985 }
20986 run_test 230w "non-recursive mode dir migration"
20987
20988 test_231a()
20989 {
20990         # For simplicity this test assumes that max_pages_per_rpc
20991         # is the same across all OSCs
20992         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20993         local bulk_size=$((max_pages * PAGE_SIZE))
20994         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20995                                        head -n 1)
20996
20997         mkdir -p $DIR/$tdir
20998         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20999                 error "failed to set stripe with -S ${brw_size}M option"
21000
21001         # clear the OSC stats
21002         $LCTL set_param osc.*.stats=0 &>/dev/null
21003         stop_writeback
21004
21005         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21006         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21007                 oflag=direct &>/dev/null || error "dd failed"
21008
21009         sync; sleep 1; sync # just to be safe
21010         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21011         if [ x$nrpcs != "x1" ]; then
21012                 $LCTL get_param osc.*.stats
21013                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21014         fi
21015
21016         start_writeback
21017         # Drop the OSC cache, otherwise we will read from it
21018         cancel_lru_locks osc
21019
21020         # clear the OSC stats
21021         $LCTL set_param osc.*.stats=0 &>/dev/null
21022
21023         # Client reads $bulk_size.
21024         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21025                 iflag=direct &>/dev/null || error "dd failed"
21026
21027         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21028         if [ x$nrpcs != "x1" ]; then
21029                 $LCTL get_param osc.*.stats
21030                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21031         fi
21032 }
21033 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21034
21035 test_231b() {
21036         mkdir -p $DIR/$tdir
21037         local i
21038         for i in {0..1023}; do
21039                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21040                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21041                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21042         done
21043         sync
21044 }
21045 run_test 231b "must not assert on fully utilized OST request buffer"
21046
21047 test_232a() {
21048         mkdir -p $DIR/$tdir
21049         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21050
21051         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21052         do_facet ost1 $LCTL set_param fail_loc=0x31c
21053
21054         # ignore dd failure
21055         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21056
21057         do_facet ost1 $LCTL set_param fail_loc=0
21058         umount_client $MOUNT || error "umount failed"
21059         mount_client $MOUNT || error "mount failed"
21060         stop ost1 || error "cannot stop ost1"
21061         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21062 }
21063 run_test 232a "failed lock should not block umount"
21064
21065 test_232b() {
21066         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21067                 skip "Need MDS version at least 2.10.58"
21068
21069         mkdir -p $DIR/$tdir
21070         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21071         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21072         sync
21073         cancel_lru_locks osc
21074
21075         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21076         do_facet ost1 $LCTL set_param fail_loc=0x31c
21077
21078         # ignore failure
21079         $LFS data_version $DIR/$tdir/$tfile || true
21080
21081         do_facet ost1 $LCTL set_param fail_loc=0
21082         umount_client $MOUNT || error "umount failed"
21083         mount_client $MOUNT || error "mount failed"
21084         stop ost1 || error "cannot stop ost1"
21085         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21086 }
21087 run_test 232b "failed data version lock should not block umount"
21088
21089 test_233a() {
21090         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21091                 skip "Need MDS version at least 2.3.64"
21092         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21093
21094         local fid=$($LFS path2fid $MOUNT)
21095
21096         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21097                 error "cannot access $MOUNT using its FID '$fid'"
21098 }
21099 run_test 233a "checking that OBF of the FS root succeeds"
21100
21101 test_233b() {
21102         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21103                 skip "Need MDS version at least 2.5.90"
21104         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21105
21106         local fid=$($LFS path2fid $MOUNT/.lustre)
21107
21108         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21109                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21110
21111         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21112         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21113                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21114 }
21115 run_test 233b "checking that OBF of the FS .lustre succeeds"
21116
21117 test_234() {
21118         local p="$TMP/sanityN-$TESTNAME.parameters"
21119         save_lustre_params client "llite.*.xattr_cache" > $p
21120         lctl set_param llite.*.xattr_cache 1 ||
21121                 skip_env "xattr cache is not supported"
21122
21123         mkdir -p $DIR/$tdir || error "mkdir failed"
21124         touch $DIR/$tdir/$tfile || error "touch failed"
21125         # OBD_FAIL_LLITE_XATTR_ENOMEM
21126         $LCTL set_param fail_loc=0x1405
21127         getfattr -n user.attr $DIR/$tdir/$tfile &&
21128                 error "getfattr should have failed with ENOMEM"
21129         $LCTL set_param fail_loc=0x0
21130         rm -rf $DIR/$tdir
21131
21132         restore_lustre_params < $p
21133         rm -f $p
21134 }
21135 run_test 234 "xattr cache should not crash on ENOMEM"
21136
21137 test_235() {
21138         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21139                 skip "Need MDS version at least 2.4.52"
21140
21141         flock_deadlock $DIR/$tfile
21142         local RC=$?
21143         case $RC in
21144                 0)
21145                 ;;
21146                 124) error "process hangs on a deadlock"
21147                 ;;
21148                 *) error "error executing flock_deadlock $DIR/$tfile"
21149                 ;;
21150         esac
21151 }
21152 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21153
21154 #LU-2935
21155 test_236() {
21156         check_swap_layouts_support
21157
21158         local ref1=/etc/passwd
21159         local ref2=/etc/group
21160         local file1=$DIR/$tdir/f1
21161         local file2=$DIR/$tdir/f2
21162
21163         test_mkdir -c1 $DIR/$tdir
21164         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21165         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21166         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21167         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21168         local fd=$(free_fd)
21169         local cmd="exec $fd<>$file2"
21170         eval $cmd
21171         rm $file2
21172         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21173                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21174         cmd="exec $fd>&-"
21175         eval $cmd
21176         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21177
21178         #cleanup
21179         rm -rf $DIR/$tdir
21180 }
21181 run_test 236 "Layout swap on open unlinked file"
21182
21183 # LU-4659 linkea consistency
21184 test_238() {
21185         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21186                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21187                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21188                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21189
21190         touch $DIR/$tfile
21191         ln $DIR/$tfile $DIR/$tfile.lnk
21192         touch $DIR/$tfile.new
21193         mv $DIR/$tfile.new $DIR/$tfile
21194         local fid1=$($LFS path2fid $DIR/$tfile)
21195         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21196         local path1=$($LFS fid2path $FSNAME "$fid1")
21197         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21198         local path2=$($LFS fid2path $FSNAME "$fid2")
21199         [ $tfile.lnk == $path2 ] ||
21200                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21201         rm -f $DIR/$tfile*
21202 }
21203 run_test 238 "Verify linkea consistency"
21204
21205 test_239A() { # was test_239
21206         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21207                 skip "Need MDS version at least 2.5.60"
21208
21209         local list=$(comma_list $(mdts_nodes))
21210
21211         mkdir -p $DIR/$tdir
21212         createmany -o $DIR/$tdir/f- 5000
21213         unlinkmany $DIR/$tdir/f- 5000
21214         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21215                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21216         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21217                         osp.*MDT*.sync_in_flight" | calc_sum)
21218         [ "$changes" -eq 0 ] || error "$changes not synced"
21219 }
21220 run_test 239A "osp_sync test"
21221
21222 test_239a() { #LU-5297
21223         remote_mds_nodsh && skip "remote MDS with nodsh"
21224
21225         touch $DIR/$tfile
21226         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21227         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21228         chgrp $RUNAS_GID $DIR/$tfile
21229         wait_delete_completed
21230 }
21231 run_test 239a "process invalid osp sync record correctly"
21232
21233 test_239b() { #LU-5297
21234         remote_mds_nodsh && skip "remote MDS with nodsh"
21235
21236         touch $DIR/$tfile1
21237         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21238         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21239         chgrp $RUNAS_GID $DIR/$tfile1
21240         wait_delete_completed
21241         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21242         touch $DIR/$tfile2
21243         chgrp $RUNAS_GID $DIR/$tfile2
21244         wait_delete_completed
21245 }
21246 run_test 239b "process osp sync record with ENOMEM error correctly"
21247
21248 test_240() {
21249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21250         remote_mds_nodsh && skip "remote MDS with nodsh"
21251
21252         mkdir -p $DIR/$tdir
21253
21254         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21255                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21256         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21257                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21258
21259         umount_client $MOUNT || error "umount failed"
21260         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21261         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21262         mount_client $MOUNT || error "failed to mount client"
21263
21264         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21265         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21266 }
21267 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21268
21269 test_241_bio() {
21270         local count=$1
21271         local bsize=$2
21272
21273         for LOOP in $(seq $count); do
21274                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21275                 cancel_lru_locks $OSC || true
21276         done
21277 }
21278
21279 test_241_dio() {
21280         local count=$1
21281         local bsize=$2
21282
21283         for LOOP in $(seq $1); do
21284                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21285                         2>/dev/null
21286         done
21287 }
21288
21289 test_241a() { # was test_241
21290         local bsize=$PAGE_SIZE
21291
21292         (( bsize < 40960 )) && bsize=40960
21293         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21294         ls -la $DIR/$tfile
21295         cancel_lru_locks $OSC
21296         test_241_bio 1000 $bsize &
21297         PID=$!
21298         test_241_dio 1000 $bsize
21299         wait $PID
21300 }
21301 run_test 241a "bio vs dio"
21302
21303 test_241b() {
21304         local bsize=$PAGE_SIZE
21305
21306         (( bsize < 40960 )) && bsize=40960
21307         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21308         ls -la $DIR/$tfile
21309         test_241_dio 1000 $bsize &
21310         PID=$!
21311         test_241_dio 1000 $bsize
21312         wait $PID
21313 }
21314 run_test 241b "dio vs dio"
21315
21316 test_242() {
21317         remote_mds_nodsh && skip "remote MDS with nodsh"
21318
21319         mkdir_on_mdt0 $DIR/$tdir
21320         touch $DIR/$tdir/$tfile
21321
21322         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21323         do_facet mds1 lctl set_param fail_loc=0x105
21324         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21325
21326         do_facet mds1 lctl set_param fail_loc=0
21327         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21328 }
21329 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21330
21331 test_243()
21332 {
21333         test_mkdir $DIR/$tdir
21334         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21335 }
21336 run_test 243 "various group lock tests"
21337
21338 test_244a()
21339 {
21340         test_mkdir $DIR/$tdir
21341         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21342         sendfile_grouplock $DIR/$tdir/$tfile || \
21343                 error "sendfile+grouplock failed"
21344         rm -rf $DIR/$tdir
21345 }
21346 run_test 244a "sendfile with group lock tests"
21347
21348 test_244b()
21349 {
21350         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21351
21352         local threads=50
21353         local size=$((1024*1024))
21354
21355         test_mkdir $DIR/$tdir
21356         for i in $(seq 1 $threads); do
21357                 local file=$DIR/$tdir/file_$((i / 10))
21358                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21359                 local pids[$i]=$!
21360         done
21361         for i in $(seq 1 $threads); do
21362                 wait ${pids[$i]}
21363         done
21364 }
21365 run_test 244b "multi-threaded write with group lock"
21366
21367 test_245a() {
21368         local flagname="multi_mod_rpcs"
21369         local connect_data_name="max_mod_rpcs"
21370         local out
21371
21372         # check if multiple modify RPCs flag is set
21373         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21374                 grep "connect_flags:")
21375         echo "$out"
21376
21377         echo "$out" | grep -qw $flagname
21378         if [ $? -ne 0 ]; then
21379                 echo "connect flag $flagname is not set"
21380                 return
21381         fi
21382
21383         # check if multiple modify RPCs data is set
21384         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21385         echo "$out"
21386
21387         echo "$out" | grep -qw $connect_data_name ||
21388                 error "import should have connect data $connect_data_name"
21389 }
21390 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21391
21392 test_245b() {
21393         local flagname="multi_mod_rpcs"
21394         local connect_data_name="max_mod_rpcs"
21395         local out
21396
21397         remote_mds_nodsh && skip "remote MDS with nodsh"
21398         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21399
21400         # check if multiple modify RPCs flag is set
21401         out=$(do_facet mds1 \
21402               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21403               grep "connect_flags:")
21404         echo "$out"
21405
21406         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21407
21408         # check if multiple modify RPCs data is set
21409         out=$(do_facet mds1 \
21410               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21411
21412         [[ "$out" =~ $connect_data_name ]] ||
21413                 {
21414                         echo "$out"
21415                         error "missing connect data $connect_data_name"
21416                 }
21417 }
21418 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21419
21420 cleanup_247() {
21421         local submount=$1
21422
21423         trap 0
21424         umount_client $submount
21425         rmdir $submount
21426 }
21427
21428 test_247a() {
21429         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21430                 grep -q subtree ||
21431                 skip_env "Fileset feature is not supported"
21432
21433         local submount=${MOUNT}_$tdir
21434
21435         mkdir $MOUNT/$tdir
21436         mkdir -p $submount || error "mkdir $submount failed"
21437         FILESET="$FILESET/$tdir" mount_client $submount ||
21438                 error "mount $submount failed"
21439         trap "cleanup_247 $submount" EXIT
21440         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21441         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21442                 error "read $MOUNT/$tdir/$tfile failed"
21443         cleanup_247 $submount
21444 }
21445 run_test 247a "mount subdir as fileset"
21446
21447 test_247b() {
21448         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21449                 skip_env "Fileset feature is not supported"
21450
21451         local submount=${MOUNT}_$tdir
21452
21453         rm -rf $MOUNT/$tdir
21454         mkdir -p $submount || error "mkdir $submount failed"
21455         SKIP_FILESET=1
21456         FILESET="$FILESET/$tdir" mount_client $submount &&
21457                 error "mount $submount should fail"
21458         rmdir $submount
21459 }
21460 run_test 247b "mount subdir that dose not exist"
21461
21462 test_247c() {
21463         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21464                 skip_env "Fileset feature is not supported"
21465
21466         local submount=${MOUNT}_$tdir
21467
21468         mkdir -p $MOUNT/$tdir/dir1
21469         mkdir -p $submount || error "mkdir $submount failed"
21470         trap "cleanup_247 $submount" EXIT
21471         FILESET="$FILESET/$tdir" mount_client $submount ||
21472                 error "mount $submount failed"
21473         local fid=$($LFS path2fid $MOUNT/)
21474         $LFS fid2path $submount $fid && error "fid2path should fail"
21475         cleanup_247 $submount
21476 }
21477 run_test 247c "running fid2path outside subdirectory root"
21478
21479 test_247d() {
21480         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21481                 skip "Fileset feature is not supported"
21482
21483         local submount=${MOUNT}_$tdir
21484
21485         mkdir -p $MOUNT/$tdir/dir1
21486         mkdir -p $submount || error "mkdir $submount failed"
21487         FILESET="$FILESET/$tdir" mount_client $submount ||
21488                 error "mount $submount failed"
21489         trap "cleanup_247 $submount" EXIT
21490
21491         local td=$submount/dir1
21492         local fid=$($LFS path2fid $td)
21493         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21494
21495         # check that we get the same pathname back
21496         local rootpath
21497         local found
21498         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21499                 echo "$rootpath $fid"
21500                 found=$($LFS fid2path $rootpath "$fid")
21501                 [ -n "$found" ] || error "fid2path should succeed"
21502                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21503         done
21504         # check wrong root path format
21505         rootpath=$submount"_wrong"
21506         found=$($LFS fid2path $rootpath "$fid")
21507         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21508
21509         cleanup_247 $submount
21510 }
21511 run_test 247d "running fid2path inside subdirectory root"
21512
21513 # LU-8037
21514 test_247e() {
21515         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21516                 grep -q subtree ||
21517                 skip "Fileset feature is not supported"
21518
21519         local submount=${MOUNT}_$tdir
21520
21521         mkdir $MOUNT/$tdir
21522         mkdir -p $submount || error "mkdir $submount failed"
21523         FILESET="$FILESET/.." mount_client $submount &&
21524                 error "mount $submount should fail"
21525         rmdir $submount
21526 }
21527 run_test 247e "mount .. as fileset"
21528
21529 test_247f() {
21530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21531         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21532                 skip "Need at least version 2.13.52"
21533         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21534                 skip "Need at least version 2.14.50"
21535         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21536                 grep -q subtree ||
21537                 skip "Fileset feature is not supported"
21538
21539         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21540         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21541                 error "mkdir remote failed"
21542         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21543                 error "mkdir remote/subdir failed"
21544         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21545                 error "mkdir striped failed"
21546         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21547
21548         local submount=${MOUNT}_$tdir
21549
21550         mkdir -p $submount || error "mkdir $submount failed"
21551         stack_trap "rmdir $submount"
21552
21553         local dir
21554         local stat
21555         local fileset=$FILESET
21556         local mdts=$(comma_list $(mdts_nodes))
21557
21558         stat=$(do_facet mds1 $LCTL get_param -n \
21559                 mdt.*MDT0000.enable_remote_subdir_mount)
21560         stack_trap "do_nodes $mdts $LCTL set_param \
21561                 mdt.*.enable_remote_subdir_mount=$stat"
21562
21563         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21564         stack_trap "umount_client $submount"
21565         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21566                 error "mount remote dir $dir should fail"
21567
21568         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21569                 $tdir/striped/. ; do
21570                 FILESET="$fileset/$dir" mount_client $submount ||
21571                         error "mount $dir failed"
21572                 umount_client $submount
21573         done
21574
21575         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21576         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21577                 error "mount $tdir/remote failed"
21578 }
21579 run_test 247f "mount striped or remote directory as fileset"
21580
21581 test_247g() {
21582         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21583         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21584                 skip "Need at least version 2.14.50"
21585
21586         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21587                 error "mkdir $tdir failed"
21588         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21589
21590         local submount=${MOUNT}_$tdir
21591
21592         mkdir -p $submount || error "mkdir $submount failed"
21593         stack_trap "rmdir $submount"
21594
21595         FILESET="$fileset/$tdir" mount_client $submount ||
21596                 error "mount $dir failed"
21597         stack_trap "umount $submount"
21598
21599         local mdts=$(comma_list $(mdts_nodes))
21600
21601         local nrpcs
21602
21603         stat $submount > /dev/null
21604         cancel_lru_locks $MDC
21605         stat $submount > /dev/null
21606         stat $submount/$tfile > /dev/null
21607         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21608         stat $submount/$tfile > /dev/null
21609         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21610                 awk '/getattr/ {sum += $2} END {print sum}')
21611
21612         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21613 }
21614 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21615
21616 test_248a() {
21617         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21618         [ -z "$fast_read_sav" ] && skip "no fast read support"
21619
21620         # create a large file for fast read verification
21621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21622
21623         # make sure the file is created correctly
21624         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21625                 { rm -f $DIR/$tfile; skip "file creation error"; }
21626
21627         echo "Test 1: verify that fast read is 4 times faster on cache read"
21628
21629         # small read with fast read enabled
21630         $LCTL set_param -n llite.*.fast_read=1
21631         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21632                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21633                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21634         # small read with fast read disabled
21635         $LCTL set_param -n llite.*.fast_read=0
21636         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21637                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21638                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21639
21640         # verify that fast read is 4 times faster for cache read
21641         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21642                 error_not_in_vm "fast read was not 4 times faster: " \
21643                            "$t_fast vs $t_slow"
21644
21645         echo "Test 2: verify the performance between big and small read"
21646         $LCTL set_param -n llite.*.fast_read=1
21647
21648         # 1k non-cache read
21649         cancel_lru_locks osc
21650         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21651                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21652                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21653
21654         # 1M non-cache read
21655         cancel_lru_locks osc
21656         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21657                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21658                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21659
21660         # verify that big IO is not 4 times faster than small IO
21661         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21662                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21663
21664         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21665         rm -f $DIR/$tfile
21666 }
21667 run_test 248a "fast read verification"
21668
21669 test_248b() {
21670         # Default short_io_bytes=16384, try both smaller and larger sizes.
21671         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21672         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21673         echo "bs=53248 count=113 normal buffered write"
21674         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21675                 error "dd of initial data file failed"
21676         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21677
21678         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21679         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21680                 error "dd with sync normal writes failed"
21681         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21682
21683         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21684         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21685                 error "dd with sync small writes failed"
21686         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21687
21688         cancel_lru_locks osc
21689
21690         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21691         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21692         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21693         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21694                 iflag=direct || error "dd with O_DIRECT small read failed"
21695         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21696         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21697                 error "compare $TMP/$tfile.1 failed"
21698
21699         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21700         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21701
21702         # just to see what the maximum tunable value is, and test parsing
21703         echo "test invalid parameter 2MB"
21704         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21705                 error "too-large short_io_bytes allowed"
21706         echo "test maximum parameter 512KB"
21707         # if we can set a larger short_io_bytes, run test regardless of version
21708         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21709                 # older clients may not allow setting it this large, that's OK
21710                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21711                         skip "Need at least client version 2.13.50"
21712                 error "medium short_io_bytes failed"
21713         fi
21714         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21715         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21716
21717         echo "test large parameter 64KB"
21718         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21719         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21720
21721         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21722         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21723                 error "dd with sync large writes failed"
21724         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21725
21726         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21727         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21728         num=$((113 * 4096 / PAGE_SIZE))
21729         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21730         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21731                 error "dd with O_DIRECT large writes failed"
21732         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21733                 error "compare $DIR/$tfile.3 failed"
21734
21735         cancel_lru_locks osc
21736
21737         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21738         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21739                 error "dd with O_DIRECT large read failed"
21740         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21741                 error "compare $TMP/$tfile.2 failed"
21742
21743         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21744         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21745                 error "dd with O_DIRECT large read failed"
21746         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21747                 error "compare $TMP/$tfile.3 failed"
21748 }
21749 run_test 248b "test short_io read and write for both small and large sizes"
21750
21751 test_249() { # LU-7890
21752         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21753                 skip "Need at least version 2.8.54"
21754
21755         rm -f $DIR/$tfile
21756         $LFS setstripe -c 1 $DIR/$tfile
21757         # Offset 2T == 4k * 512M
21758         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21759                 error "dd to 2T offset failed"
21760 }
21761 run_test 249 "Write above 2T file size"
21762
21763 test_250() {
21764         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21765          && skip "no 16TB file size limit on ZFS"
21766
21767         $LFS setstripe -c 1 $DIR/$tfile
21768         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21769         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21770         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21771         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21772                 conv=notrunc,fsync && error "append succeeded"
21773         return 0
21774 }
21775 run_test 250 "Write above 16T limit"
21776
21777 test_251() {
21778         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21779
21780         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21781         #Skip once - writing the first stripe will succeed
21782         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21783         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21784                 error "short write happened"
21785
21786         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21787         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21788                 error "short read happened"
21789
21790         rm -f $DIR/$tfile
21791 }
21792 run_test 251 "Handling short read and write correctly"
21793
21794 test_252() {
21795         remote_mds_nodsh && skip "remote MDS with nodsh"
21796         remote_ost_nodsh && skip "remote OST with nodsh"
21797         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21798                 skip_env "ldiskfs only test"
21799         fi
21800
21801         local tgt
21802         local dev
21803         local out
21804         local uuid
21805         local num
21806         local gen
21807
21808         # check lr_reader on OST0000
21809         tgt=ost1
21810         dev=$(facet_device $tgt)
21811         out=$(do_facet $tgt $LR_READER $dev)
21812         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21813         echo "$out"
21814         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21815         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21816                 error "Invalid uuid returned by $LR_READER on target $tgt"
21817         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21818
21819         # check lr_reader -c on MDT0000
21820         tgt=mds1
21821         dev=$(facet_device $tgt)
21822         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21823                 skip "$LR_READER does not support additional options"
21824         fi
21825         out=$(do_facet $tgt $LR_READER -c $dev)
21826         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21827         echo "$out"
21828         num=$(echo "$out" | grep -c "mdtlov")
21829         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21830                 error "Invalid number of mdtlov clients returned by $LR_READER"
21831         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21832
21833         # check lr_reader -cr on MDT0000
21834         out=$(do_facet $tgt $LR_READER -cr $dev)
21835         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21836         echo "$out"
21837         echo "$out" | grep -q "^reply_data:$" ||
21838                 error "$LR_READER should have returned 'reply_data' section"
21839         num=$(echo "$out" | grep -c "client_generation")
21840         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21841 }
21842 run_test 252 "check lr_reader tool"
21843
21844 test_253() {
21845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21846         remote_mds_nodsh && skip "remote MDS with nodsh"
21847         remote_mgs_nodsh && skip "remote MGS with nodsh"
21848
21849         local ostidx=0
21850         local rc=0
21851         local ost_name=$(ostname_from_index $ostidx)
21852
21853         # on the mdt's osc
21854         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21855         do_facet $SINGLEMDS $LCTL get_param -n \
21856                 osp.$mdtosc_proc1.reserved_mb_high ||
21857                 skip  "remote MDS does not support reserved_mb_high"
21858
21859         rm -rf $DIR/$tdir
21860         wait_mds_ost_sync
21861         wait_delete_completed
21862         mkdir $DIR/$tdir
21863
21864         pool_add $TESTNAME || error "Pool creation failed"
21865         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21866
21867         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21868                 error "Setstripe failed"
21869
21870         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21871
21872         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21873                     grep "watermarks")
21874         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21875
21876         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21877                         osp.$mdtosc_proc1.prealloc_status)
21878         echo "prealloc_status $oa_status"
21879
21880         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21881                 error "File creation should fail"
21882
21883         #object allocation was stopped, but we still able to append files
21884         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21885                 oflag=append || error "Append failed"
21886
21887         rm -f $DIR/$tdir/$tfile.0
21888
21889         # For this test, we want to delete the files we created to go out of
21890         # space but leave the watermark, so we remain nearly out of space
21891         ost_watermarks_enospc_delete_files $tfile $ostidx
21892
21893         wait_delete_completed
21894
21895         sleep_maxage
21896
21897         for i in $(seq 10 12); do
21898                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21899                         2>/dev/null || error "File creation failed after rm"
21900         done
21901
21902         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21903                         osp.$mdtosc_proc1.prealloc_status)
21904         echo "prealloc_status $oa_status"
21905
21906         if (( oa_status != 0 )); then
21907                 error "Object allocation still disable after rm"
21908         fi
21909 }
21910 run_test 253 "Check object allocation limit"
21911
21912 test_254() {
21913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21914         remote_mds_nodsh && skip "remote MDS with nodsh"
21915
21916         local mdt=$(facet_svc $SINGLEMDS)
21917
21918         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21919                 skip "MDS does not support changelog_size"
21920
21921         local cl_user
21922
21923         changelog_register || error "changelog_register failed"
21924
21925         changelog_clear 0 || error "changelog_clear failed"
21926
21927         local size1=$(do_facet $SINGLEMDS \
21928                       $LCTL get_param -n mdd.$mdt.changelog_size)
21929         echo "Changelog size $size1"
21930
21931         rm -rf $DIR/$tdir
21932         $LFS mkdir -i 0 $DIR/$tdir
21933         # change something
21934         mkdir -p $DIR/$tdir/pics/2008/zachy
21935         touch $DIR/$tdir/pics/2008/zachy/timestamp
21936         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21937         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21938         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21939         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21940         rm $DIR/$tdir/pics/desktop.jpg
21941
21942         local size2=$(do_facet $SINGLEMDS \
21943                       $LCTL get_param -n mdd.$mdt.changelog_size)
21944         echo "Changelog size after work $size2"
21945
21946         (( $size2 > $size1 )) ||
21947                 error "new Changelog size=$size2 less than old size=$size1"
21948 }
21949 run_test 254 "Check changelog size"
21950
21951 ladvise_no_type()
21952 {
21953         local type=$1
21954         local file=$2
21955
21956         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21957                 awk -F: '{print $2}' | grep $type > /dev/null
21958         if [ $? -ne 0 ]; then
21959                 return 0
21960         fi
21961         return 1
21962 }
21963
21964 ladvise_no_ioctl()
21965 {
21966         local file=$1
21967
21968         lfs ladvise -a willread $file > /dev/null 2>&1
21969         if [ $? -eq 0 ]; then
21970                 return 1
21971         fi
21972
21973         lfs ladvise -a willread $file 2>&1 |
21974                 grep "Inappropriate ioctl for device" > /dev/null
21975         if [ $? -eq 0 ]; then
21976                 return 0
21977         fi
21978         return 1
21979 }
21980
21981 percent() {
21982         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21983 }
21984
21985 # run a random read IO workload
21986 # usage: random_read_iops <filename> <filesize> <iosize>
21987 random_read_iops() {
21988         local file=$1
21989         local fsize=$2
21990         local iosize=${3:-4096}
21991
21992         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21993                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21994 }
21995
21996 drop_file_oss_cache() {
21997         local file="$1"
21998         local nodes="$2"
21999
22000         $LFS ladvise -a dontneed $file 2>/dev/null ||
22001                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22002 }
22003
22004 ladvise_willread_performance()
22005 {
22006         local repeat=10
22007         local average_origin=0
22008         local average_cache=0
22009         local average_ladvise=0
22010
22011         for ((i = 1; i <= $repeat; i++)); do
22012                 echo "Iter $i/$repeat: reading without willread hint"
22013                 cancel_lru_locks osc
22014                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22015                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22016                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22017                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22018
22019                 cancel_lru_locks osc
22020                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22021                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22022                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22023
22024                 cancel_lru_locks osc
22025                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22026                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22027                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22028                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22029                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22030         done
22031         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22032         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22033         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22034
22035         speedup_cache=$(percent $average_cache $average_origin)
22036         speedup_ladvise=$(percent $average_ladvise $average_origin)
22037
22038         echo "Average uncached read: $average_origin"
22039         echo "Average speedup with OSS cached read: " \
22040                 "$average_cache = +$speedup_cache%"
22041         echo "Average speedup with ladvise willread: " \
22042                 "$average_ladvise = +$speedup_ladvise%"
22043
22044         local lowest_speedup=20
22045         if (( ${average_cache%.*} < $lowest_speedup )); then
22046                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22047                      " got $average_cache%. Skipping ladvise willread check."
22048                 return 0
22049         fi
22050
22051         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22052         # it is still good to run until then to exercise 'ladvise willread'
22053         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22054                 [ "$ost1_FSTYPE" = "zfs" ] &&
22055                 echo "osd-zfs does not support dontneed or drop_caches" &&
22056                 return 0
22057
22058         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22059         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22060                 error_not_in_vm "Speedup with willread is less than " \
22061                         "$lowest_speedup%, got $average_ladvise%"
22062 }
22063
22064 test_255a() {
22065         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22066                 skip "lustre < 2.8.54 does not support ladvise "
22067         remote_ost_nodsh && skip "remote OST with nodsh"
22068
22069         stack_trap "rm -f $DIR/$tfile"
22070         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22071
22072         ladvise_no_type willread $DIR/$tfile &&
22073                 skip "willread ladvise is not supported"
22074
22075         ladvise_no_ioctl $DIR/$tfile &&
22076                 skip "ladvise ioctl is not supported"
22077
22078         local size_mb=100
22079         local size=$((size_mb * 1048576))
22080         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22081                 error "dd to $DIR/$tfile failed"
22082
22083         lfs ladvise -a willread $DIR/$tfile ||
22084                 error "Ladvise failed with no range argument"
22085
22086         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22087                 error "Ladvise failed with no -l or -e argument"
22088
22089         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22090                 error "Ladvise failed with only -e argument"
22091
22092         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22093                 error "Ladvise failed with only -l argument"
22094
22095         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22096                 error "End offset should not be smaller than start offset"
22097
22098         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22099                 error "End offset should not be equal to start offset"
22100
22101         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22102                 error "Ladvise failed with overflowing -s argument"
22103
22104         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22105                 error "Ladvise failed with overflowing -e argument"
22106
22107         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22108                 error "Ladvise failed with overflowing -l argument"
22109
22110         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22111                 error "Ladvise succeeded with conflicting -l and -e arguments"
22112
22113         echo "Synchronous ladvise should wait"
22114         local delay=4
22115 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22116         do_nodes $(comma_list $(osts_nodes)) \
22117                 $LCTL set_param fail_val=$delay fail_loc=0x237
22118
22119         local start_ts=$SECONDS
22120         lfs ladvise -a willread $DIR/$tfile ||
22121                 error "Ladvise failed with no range argument"
22122         local end_ts=$SECONDS
22123         local inteval_ts=$((end_ts - start_ts))
22124
22125         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22126                 error "Synchronous advice didn't wait reply"
22127         fi
22128
22129         echo "Asynchronous ladvise shouldn't wait"
22130         local start_ts=$SECONDS
22131         lfs ladvise -a willread -b $DIR/$tfile ||
22132                 error "Ladvise failed with no range argument"
22133         local end_ts=$SECONDS
22134         local inteval_ts=$((end_ts - start_ts))
22135
22136         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22137                 error "Asynchronous advice blocked"
22138         fi
22139
22140         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22141         ladvise_willread_performance
22142 }
22143 run_test 255a "check 'lfs ladvise -a willread'"
22144
22145 facet_meminfo() {
22146         local facet=$1
22147         local info=$2
22148
22149         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22150 }
22151
22152 test_255b() {
22153         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22154                 skip "lustre < 2.8.54 does not support ladvise "
22155         remote_ost_nodsh && skip "remote OST with nodsh"
22156
22157         stack_trap "rm -f $DIR/$tfile"
22158         lfs setstripe -c 1 -i 0 $DIR/$tfile
22159
22160         ladvise_no_type dontneed $DIR/$tfile &&
22161                 skip "dontneed ladvise is not supported"
22162
22163         ladvise_no_ioctl $DIR/$tfile &&
22164                 skip "ladvise ioctl is not supported"
22165
22166         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22167                 [ "$ost1_FSTYPE" = "zfs" ] &&
22168                 skip "zfs-osd does not support 'ladvise dontneed'"
22169
22170         local size_mb=100
22171         local size=$((size_mb * 1048576))
22172         # In order to prevent disturbance of other processes, only check 3/4
22173         # of the memory usage
22174         local kibibytes=$((size_mb * 1024 * 3 / 4))
22175
22176         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22177                 error "dd to $DIR/$tfile failed"
22178
22179         #force write to complete before dropping OST cache & checking memory
22180         sync
22181
22182         local total=$(facet_meminfo ost1 MemTotal)
22183         echo "Total memory: $total KiB"
22184
22185         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22186         local before_read=$(facet_meminfo ost1 Cached)
22187         echo "Cache used before read: $before_read KiB"
22188
22189         lfs ladvise -a willread $DIR/$tfile ||
22190                 error "Ladvise willread failed"
22191         local after_read=$(facet_meminfo ost1 Cached)
22192         echo "Cache used after read: $after_read KiB"
22193
22194         lfs ladvise -a dontneed $DIR/$tfile ||
22195                 error "Ladvise dontneed again failed"
22196         local no_read=$(facet_meminfo ost1 Cached)
22197         echo "Cache used after dontneed ladvise: $no_read KiB"
22198
22199         if [ $total -lt $((before_read + kibibytes)) ]; then
22200                 echo "Memory is too small, abort checking"
22201                 return 0
22202         fi
22203
22204         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22205                 error "Ladvise willread should use more memory" \
22206                         "than $kibibytes KiB"
22207         fi
22208
22209         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22210                 error "Ladvise dontneed should release more memory" \
22211                         "than $kibibytes KiB"
22212         fi
22213 }
22214 run_test 255b "check 'lfs ladvise -a dontneed'"
22215
22216 test_255c() {
22217         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22218                 skip "lustre < 2.10.50 does not support lockahead"
22219
22220         local ost1_imp=$(get_osc_import_name client ost1)
22221         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22222                          cut -d'.' -f2)
22223         local count
22224         local new_count
22225         local difference
22226         local i
22227         local rc
22228
22229         test_mkdir -p $DIR/$tdir
22230         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22231
22232         #test 10 returns only success/failure
22233         i=10
22234         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22235         rc=$?
22236         if [ $rc -eq 255 ]; then
22237                 error "Ladvise test${i} failed, ${rc}"
22238         fi
22239
22240         #test 11 counts lock enqueue requests, all others count new locks
22241         i=11
22242         count=$(do_facet ost1 \
22243                 $LCTL get_param -n ost.OSS.ost.stats)
22244         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22245
22246         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22247         rc=$?
22248         if [ $rc -eq 255 ]; then
22249                 error "Ladvise test${i} failed, ${rc}"
22250         fi
22251
22252         new_count=$(do_facet ost1 \
22253                 $LCTL get_param -n ost.OSS.ost.stats)
22254         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22255                    awk '{ print $2 }')
22256
22257         difference="$((new_count - count))"
22258         if [ $difference -ne $rc ]; then
22259                 error "Ladvise test${i}, bad enqueue count, returned " \
22260                       "${rc}, actual ${difference}"
22261         fi
22262
22263         for i in $(seq 12 21); do
22264                 # If we do not do this, we run the risk of having too many
22265                 # locks and starting lock cancellation while we are checking
22266                 # lock counts.
22267                 cancel_lru_locks osc
22268
22269                 count=$($LCTL get_param -n \
22270                        ldlm.namespaces.$imp_name.lock_unused_count)
22271
22272                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22273                 rc=$?
22274                 if [ $rc -eq 255 ]; then
22275                         error "Ladvise test ${i} failed, ${rc}"
22276                 fi
22277
22278                 new_count=$($LCTL get_param -n \
22279                        ldlm.namespaces.$imp_name.lock_unused_count)
22280                 difference="$((new_count - count))"
22281
22282                 # Test 15 output is divided by 100 to map down to valid return
22283                 if [ $i -eq 15 ]; then
22284                         rc="$((rc * 100))"
22285                 fi
22286
22287                 if [ $difference -ne $rc ]; then
22288                         error "Ladvise test ${i}, bad lock count, returned " \
22289                               "${rc}, actual ${difference}"
22290                 fi
22291         done
22292
22293         #test 22 returns only success/failure
22294         i=22
22295         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22296         rc=$?
22297         if [ $rc -eq 255 ]; then
22298                 error "Ladvise test${i} failed, ${rc}"
22299         fi
22300 }
22301 run_test 255c "suite of ladvise lockahead tests"
22302
22303 test_256() {
22304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22305         remote_mds_nodsh && skip "remote MDS with nodsh"
22306         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22307         changelog_users $SINGLEMDS | grep "^cl" &&
22308                 skip "active changelog user"
22309
22310         local cl_user
22311         local cat_sl
22312         local mdt_dev
22313
22314         mdt_dev=$(facet_device $SINGLEMDS)
22315         echo $mdt_dev
22316
22317         changelog_register || error "changelog_register failed"
22318
22319         rm -rf $DIR/$tdir
22320         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22321
22322         changelog_clear 0 || error "changelog_clear failed"
22323
22324         # change something
22325         touch $DIR/$tdir/{1..10}
22326
22327         # stop the MDT
22328         stop $SINGLEMDS || error "Fail to stop MDT"
22329
22330         # remount the MDT
22331         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22332                 error "Fail to start MDT"
22333
22334         #after mount new plainllog is used
22335         touch $DIR/$tdir/{11..19}
22336         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22337         stack_trap "rm -f $tmpfile"
22338         cat_sl=$(do_facet $SINGLEMDS "sync; \
22339                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22340                  llog_reader $tmpfile | grep -c type=1064553b")
22341         do_facet $SINGLEMDS llog_reader $tmpfile
22342
22343         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22344
22345         changelog_clear 0 || error "changelog_clear failed"
22346
22347         cat_sl=$(do_facet $SINGLEMDS "sync; \
22348                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22349                  llog_reader $tmpfile | grep -c type=1064553b")
22350
22351         if (( cat_sl == 2 )); then
22352                 error "Empty plain llog was not deleted from changelog catalog"
22353         elif (( cat_sl != 1 )); then
22354                 error "Active plain llog shouldn't be deleted from catalog"
22355         fi
22356 }
22357 run_test 256 "Check llog delete for empty and not full state"
22358
22359 test_257() {
22360         remote_mds_nodsh && skip "remote MDS with nodsh"
22361         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22362                 skip "Need MDS version at least 2.8.55"
22363
22364         test_mkdir $DIR/$tdir
22365
22366         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22367                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22368         stat $DIR/$tdir
22369
22370 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22371         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22372         local facet=mds$((mdtidx + 1))
22373         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22374         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22375
22376         stop $facet || error "stop MDS failed"
22377         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22378                 error "start MDS fail"
22379         wait_recovery_complete $facet
22380 }
22381 run_test 257 "xattr locks are not lost"
22382
22383 # Verify we take the i_mutex when security requires it
22384 test_258a() {
22385 #define OBD_FAIL_IMUTEX_SEC 0x141c
22386         $LCTL set_param fail_loc=0x141c
22387         touch $DIR/$tfile
22388         chmod u+s $DIR/$tfile
22389         chmod a+rwx $DIR/$tfile
22390         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22391         RC=$?
22392         if [ $RC -ne 0 ]; then
22393                 error "error, failed to take i_mutex, rc=$?"
22394         fi
22395         rm -f $DIR/$tfile
22396 }
22397 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22398
22399 # Verify we do NOT take the i_mutex in the normal case
22400 test_258b() {
22401 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22402         $LCTL set_param fail_loc=0x141d
22403         touch $DIR/$tfile
22404         chmod a+rwx $DIR
22405         chmod a+rw $DIR/$tfile
22406         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22407         RC=$?
22408         if [ $RC -ne 0 ]; then
22409                 error "error, took i_mutex unnecessarily, rc=$?"
22410         fi
22411         rm -f $DIR/$tfile
22412
22413 }
22414 run_test 258b "verify i_mutex security behavior"
22415
22416 test_259() {
22417         local file=$DIR/$tfile
22418         local before
22419         local after
22420
22421         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22422
22423         stack_trap "rm -f $file" EXIT
22424
22425         wait_delete_completed
22426         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22427         echo "before: $before"
22428
22429         $LFS setstripe -i 0 -c 1 $file
22430         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22431         sync_all_data
22432         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22433         echo "after write: $after"
22434
22435 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22436         do_facet ost1 $LCTL set_param fail_loc=0x2301
22437         $TRUNCATE $file 0
22438         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22439         echo "after truncate: $after"
22440
22441         stop ost1
22442         do_facet ost1 $LCTL set_param fail_loc=0
22443         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22444         sleep 2
22445         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22446         echo "after restart: $after"
22447         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22448                 error "missing truncate?"
22449
22450         return 0
22451 }
22452 run_test 259 "crash at delayed truncate"
22453
22454 test_260() {
22455 #define OBD_FAIL_MDC_CLOSE               0x806
22456         $LCTL set_param fail_loc=0x80000806
22457         touch $DIR/$tfile
22458
22459 }
22460 run_test 260 "Check mdc_close fail"
22461
22462 ### Data-on-MDT sanity tests ###
22463 test_270a() {
22464         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22465                 skip "Need MDS version at least 2.10.55 for DoM"
22466
22467         # create DoM file
22468         local dom=$DIR/$tdir/dom_file
22469         local tmp=$DIR/$tdir/tmp_file
22470
22471         mkdir_on_mdt0 $DIR/$tdir
22472
22473         # basic checks for DoM component creation
22474         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22475                 error "Can set MDT layout to non-first entry"
22476
22477         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22478                 error "Can define multiple entries as MDT layout"
22479
22480         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22481
22482         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22483         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22484         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22485
22486         local mdtidx=$($LFS getstripe -m $dom)
22487         local mdtname=MDT$(printf %04x $mdtidx)
22488         local facet=mds$((mdtidx + 1))
22489         local space_check=1
22490
22491         # Skip free space checks with ZFS
22492         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22493
22494         # write
22495         sync
22496         local size_tmp=$((65536 * 3))
22497         local mdtfree1=$(do_facet $facet \
22498                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22499
22500         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22501         # check also direct IO along write
22502         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22503         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22504         sync
22505         cmp $tmp $dom || error "file data is different"
22506         [ $(stat -c%s $dom) == $size_tmp ] ||
22507                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22508         if [ $space_check == 1 ]; then
22509                 local mdtfree2=$(do_facet $facet \
22510                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22511
22512                 # increase in usage from by $size_tmp
22513                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22514                         error "MDT free space wrong after write: " \
22515                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22516         fi
22517
22518         # truncate
22519         local size_dom=10000
22520
22521         $TRUNCATE $dom $size_dom
22522         [ $(stat -c%s $dom) == $size_dom ] ||
22523                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22524         if [ $space_check == 1 ]; then
22525                 mdtfree1=$(do_facet $facet \
22526                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22527                 # decrease in usage from $size_tmp to new $size_dom
22528                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22529                   $(((size_tmp - size_dom) / 1024)) ] ||
22530                         error "MDT free space is wrong after truncate: " \
22531                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22532         fi
22533
22534         # append
22535         cat $tmp >> $dom
22536         sync
22537         size_dom=$((size_dom + size_tmp))
22538         [ $(stat -c%s $dom) == $size_dom ] ||
22539                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22540         if [ $space_check == 1 ]; then
22541                 mdtfree2=$(do_facet $facet \
22542                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22543                 # increase in usage by $size_tmp from previous
22544                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22545                         error "MDT free space is wrong after append: " \
22546                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22547         fi
22548
22549         # delete
22550         rm $dom
22551         if [ $space_check == 1 ]; then
22552                 mdtfree1=$(do_facet $facet \
22553                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22554                 # decrease in usage by $size_dom from previous
22555                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22556                         error "MDT free space is wrong after removal: " \
22557                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22558         fi
22559
22560         # combined striping
22561         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22562                 error "Can't create DoM + OST striping"
22563
22564         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22565         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22566         # check also direct IO along write
22567         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22568         sync
22569         cmp $tmp $dom || error "file data is different"
22570         [ $(stat -c%s $dom) == $size_tmp ] ||
22571                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22572         rm $dom $tmp
22573
22574         return 0
22575 }
22576 run_test 270a "DoM: basic functionality tests"
22577
22578 test_270b() {
22579         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22580                 skip "Need MDS version at least 2.10.55"
22581
22582         local dom=$DIR/$tdir/dom_file
22583         local max_size=1048576
22584
22585         mkdir -p $DIR/$tdir
22586         $LFS setstripe -E $max_size -L mdt $dom
22587
22588         # truncate over the limit
22589         $TRUNCATE $dom $(($max_size + 1)) &&
22590                 error "successful truncate over the maximum size"
22591         # write over the limit
22592         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22593                 error "successful write over the maximum size"
22594         # append over the limit
22595         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22596         echo "12345" >> $dom && error "successful append over the maximum size"
22597         rm $dom
22598
22599         return 0
22600 }
22601 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22602
22603 test_270c() {
22604         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22605                 skip "Need MDS version at least 2.10.55"
22606
22607         mkdir -p $DIR/$tdir
22608         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22609
22610         # check files inherit DoM EA
22611         touch $DIR/$tdir/first
22612         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22613                 error "bad pattern"
22614         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22615                 error "bad stripe count"
22616         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22617                 error "bad stripe size"
22618
22619         # check directory inherits DoM EA and uses it as default
22620         mkdir $DIR/$tdir/subdir
22621         touch $DIR/$tdir/subdir/second
22622         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22623                 error "bad pattern in sub-directory"
22624         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22625                 error "bad stripe count in sub-directory"
22626         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22627                 error "bad stripe size in sub-directory"
22628         return 0
22629 }
22630 run_test 270c "DoM: DoM EA inheritance tests"
22631
22632 test_270d() {
22633         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22634                 skip "Need MDS version at least 2.10.55"
22635
22636         mkdir -p $DIR/$tdir
22637         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22638
22639         # inherit default DoM striping
22640         mkdir $DIR/$tdir/subdir
22641         touch $DIR/$tdir/subdir/f1
22642
22643         # change default directory striping
22644         $LFS setstripe -c 1 $DIR/$tdir/subdir
22645         touch $DIR/$tdir/subdir/f2
22646         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22647                 error "wrong default striping in file 2"
22648         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22649                 error "bad pattern in file 2"
22650         return 0
22651 }
22652 run_test 270d "DoM: change striping from DoM to RAID0"
22653
22654 test_270e() {
22655         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22656                 skip "Need MDS version at least 2.10.55"
22657
22658         mkdir -p $DIR/$tdir/dom
22659         mkdir -p $DIR/$tdir/norm
22660         DOMFILES=20
22661         NORMFILES=10
22662         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22663         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22664
22665         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22666         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22667
22668         # find DoM files by layout
22669         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22670         [ $NUM -eq  $DOMFILES ] ||
22671                 error "lfs find -L: found $NUM, expected $DOMFILES"
22672         echo "Test 1: lfs find 20 DOM files by layout: OK"
22673
22674         # there should be 1 dir with default DOM striping
22675         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22676         [ $NUM -eq  1 ] ||
22677                 error "lfs find -L: found $NUM, expected 1 dir"
22678         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22679
22680         # find DoM files by stripe size
22681         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22682         [ $NUM -eq  $DOMFILES ] ||
22683                 error "lfs find -S: found $NUM, expected $DOMFILES"
22684         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22685
22686         # find files by stripe offset except DoM files
22687         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22688         [ $NUM -eq  $NORMFILES ] ||
22689                 error "lfs find -i: found $NUM, expected $NORMFILES"
22690         echo "Test 5: lfs find no DOM files by stripe index: OK"
22691         return 0
22692 }
22693 run_test 270e "DoM: lfs find with DoM files test"
22694
22695 test_270f() {
22696         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22697                 skip "Need MDS version at least 2.10.55"
22698
22699         local mdtname=${FSNAME}-MDT0000-mdtlov
22700         local dom=$DIR/$tdir/dom_file
22701         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22702                                                 lod.$mdtname.dom_stripesize)
22703         local dom_limit=131072
22704
22705         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22706         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22707                                                 lod.$mdtname.dom_stripesize)
22708         [ ${dom_limit} -eq ${dom_current} ] ||
22709                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22710
22711         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22712         $LFS setstripe -d $DIR/$tdir
22713         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22714                 error "Can't set directory default striping"
22715
22716         # exceed maximum stripe size
22717         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22718                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22719         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22720                 error "Able to create DoM component size more than LOD limit"
22721
22722         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22723         dom_current=$(do_facet mds1 $LCTL get_param -n \
22724                                                 lod.$mdtname.dom_stripesize)
22725         [ 0 -eq ${dom_current} ] ||
22726                 error "Can't set zero DoM stripe limit"
22727         rm $dom
22728
22729         # attempt to create DoM file on server with disabled DoM should
22730         # remove DoM entry from layout and be succeed
22731         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22732                 error "Can't create DoM file (DoM is disabled)"
22733         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22734                 error "File has DoM component while DoM is disabled"
22735         rm $dom
22736
22737         # attempt to create DoM file with only DoM stripe should return error
22738         $LFS setstripe -E $dom_limit -L mdt $dom &&
22739                 error "Able to create DoM-only file while DoM is disabled"
22740
22741         # too low values to be aligned with smallest stripe size 64K
22742         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22743         dom_current=$(do_facet mds1 $LCTL get_param -n \
22744                                                 lod.$mdtname.dom_stripesize)
22745         [ 30000 -eq ${dom_current} ] &&
22746                 error "Can set too small DoM stripe limit"
22747
22748         # 64K is a minimal stripe size in Lustre, expect limit of that size
22749         [ 65536 -eq ${dom_current} ] ||
22750                 error "Limit is not set to 64K but ${dom_current}"
22751
22752         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22753         dom_current=$(do_facet mds1 $LCTL get_param -n \
22754                                                 lod.$mdtname.dom_stripesize)
22755         echo $dom_current
22756         [ 2147483648 -eq ${dom_current} ] &&
22757                 error "Can set too large DoM stripe limit"
22758
22759         do_facet mds1 $LCTL set_param -n \
22760                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22761         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22762                 error "Can't create DoM component size after limit change"
22763         do_facet mds1 $LCTL set_param -n \
22764                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22765         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22766                 error "Can't create DoM file after limit decrease"
22767         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22768                 error "Can create big DoM component after limit decrease"
22769         touch ${dom}_def ||
22770                 error "Can't create file with old default layout"
22771
22772         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22773         return 0
22774 }
22775 run_test 270f "DoM: maximum DoM stripe size checks"
22776
22777 test_270g() {
22778         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22779                 skip "Need MDS version at least 2.13.52"
22780         local dom=$DIR/$tdir/$tfile
22781
22782         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22783         local lodname=${FSNAME}-MDT0000-mdtlov
22784
22785         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22786         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22787         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22788         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22789
22790         local dom_limit=1024
22791         local dom_threshold="50%"
22792
22793         $LFS setstripe -d $DIR/$tdir
22794         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22795                 error "Can't set directory default striping"
22796
22797         do_facet mds1 $LCTL set_param -n \
22798                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22799         # set 0 threshold and create DOM file to change tunable stripesize
22800         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22801         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22802                 error "Failed to create $dom file"
22803         # now tunable dom_cur_stripesize should reach maximum
22804         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22805                                         lod.${lodname}.dom_stripesize_cur_kb)
22806         [[ $dom_current == $dom_limit ]] ||
22807                 error "Current DOM stripesize is not maximum"
22808         rm $dom
22809
22810         # set threshold for further tests
22811         do_facet mds1 $LCTL set_param -n \
22812                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22813         echo "DOM threshold is $dom_threshold free space"
22814         local dom_def
22815         local dom_set
22816         # Spoof bfree to exceed threshold
22817         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22818         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22819         for spfree in 40 20 0 15 30 55; do
22820                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22821                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22822                         error "Failed to create $dom file"
22823                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22824                                         lod.${lodname}.dom_stripesize_cur_kb)
22825                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22826                 [[ $dom_def != $dom_current ]] ||
22827                         error "Default stripe size was not changed"
22828                 if (( spfree > 0 )) ; then
22829                         dom_set=$($LFS getstripe -S $dom)
22830                         (( dom_set == dom_def * 1024 )) ||
22831                                 error "DOM component size is still old"
22832                 else
22833                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22834                                 error "DoM component is set with no free space"
22835                 fi
22836                 rm $dom
22837                 dom_current=$dom_def
22838         done
22839 }
22840 run_test 270g "DoM: default DoM stripe size depends on free space"
22841
22842 test_270h() {
22843         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22844                 skip "Need MDS version at least 2.13.53"
22845
22846         local mdtname=${FSNAME}-MDT0000-mdtlov
22847         local dom=$DIR/$tdir/$tfile
22848         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22849
22850         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22851         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22852
22853         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22854         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22855                 error "can't create OST file"
22856         # mirrored file with DOM entry in the second mirror
22857         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22858                 error "can't create mirror with DoM component"
22859
22860         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22861
22862         # DOM component in the middle and has other enries in the same mirror,
22863         # should succeed but lost DoM component
22864         $LFS setstripe --copy=${dom}_1 $dom ||
22865                 error "Can't create file from OST|DOM mirror layout"
22866         # check new file has no DoM layout after all
22867         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22868                 error "File has DoM component while DoM is disabled"
22869 }
22870 run_test 270h "DoM: DoM stripe removal when disabled on server"
22871
22872 test_270i() {
22873         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22874                 skip "Need MDS version at least 2.14.54"
22875
22876         mkdir $DIR/$tdir
22877         # DoM with plain layout
22878         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22879                 error "default plain layout with DoM must fail"
22880         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
22881                 error "setstripe plain file layout with DoM must fail"
22882         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
22883                 error "default DoM layout with bad striping must fail"
22884         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
22885                 error "setstripe to DoM layout with bad striping must fail"
22886         return 0
22887 }
22888 run_test 270i "DoM: setting invalid DoM striping should fail"
22889
22890 test_271a() {
22891         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22892                 skip "Need MDS version at least 2.10.55"
22893
22894         local dom=$DIR/$tdir/dom
22895
22896         mkdir -p $DIR/$tdir
22897
22898         $LFS setstripe -E 1024K -L mdt $dom
22899
22900         lctl set_param -n mdc.*.stats=clear
22901         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22902         cat $dom > /dev/null
22903         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22904         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22905         ls $dom
22906         rm -f $dom
22907 }
22908 run_test 271a "DoM: data is cached for read after write"
22909
22910 test_271b() {
22911         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22912                 skip "Need MDS version at least 2.10.55"
22913
22914         local dom=$DIR/$tdir/dom
22915
22916         mkdir -p $DIR/$tdir
22917
22918         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22919
22920         lctl set_param -n mdc.*.stats=clear
22921         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22922         cancel_lru_locks mdc
22923         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22924         # second stat to check size is cached on client
22925         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22926         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22927         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22928         rm -f $dom
22929 }
22930 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22931
22932 test_271ba() {
22933         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22934                 skip "Need MDS version at least 2.10.55"
22935
22936         local dom=$DIR/$tdir/dom
22937
22938         mkdir -p $DIR/$tdir
22939
22940         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22941
22942         lctl set_param -n mdc.*.stats=clear
22943         lctl set_param -n osc.*.stats=clear
22944         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22945         cancel_lru_locks mdc
22946         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22947         # second stat to check size is cached on client
22948         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22949         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22950         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22951         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22952         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22953         rm -f $dom
22954 }
22955 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22956
22957
22958 get_mdc_stats() {
22959         local mdtidx=$1
22960         local param=$2
22961         local mdt=MDT$(printf %04x $mdtidx)
22962
22963         if [ -z $param ]; then
22964                 lctl get_param -n mdc.*$mdt*.stats
22965         else
22966                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22967         fi
22968 }
22969
22970 test_271c() {
22971         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22972                 skip "Need MDS version at least 2.10.55"
22973
22974         local dom=$DIR/$tdir/dom
22975
22976         mkdir -p $DIR/$tdir
22977
22978         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22979
22980         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22981         local facet=mds$((mdtidx + 1))
22982
22983         cancel_lru_locks mdc
22984         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22985         createmany -o $dom 1000
22986         lctl set_param -n mdc.*.stats=clear
22987         smalliomany -w $dom 1000 200
22988         get_mdc_stats $mdtidx
22989         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22990         # Each file has 1 open, 1 IO enqueues, total 2000
22991         # but now we have also +1 getxattr for security.capability, total 3000
22992         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22993         unlinkmany $dom 1000
22994
22995         cancel_lru_locks mdc
22996         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22997         createmany -o $dom 1000
22998         lctl set_param -n mdc.*.stats=clear
22999         smalliomany -w $dom 1000 200
23000         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23001         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23002         # for OPEN and IO lock.
23003         [ $((enq - enq_2)) -ge 1000 ] ||
23004                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23005         unlinkmany $dom 1000
23006         return 0
23007 }
23008 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23009
23010 cleanup_271def_tests() {
23011         trap 0
23012         rm -f $1
23013 }
23014
23015 test_271d() {
23016         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23017                 skip "Need MDS version at least 2.10.57"
23018
23019         local dom=$DIR/$tdir/dom
23020         local tmp=$TMP/$tfile
23021         trap "cleanup_271def_tests $tmp" EXIT
23022
23023         mkdir -p $DIR/$tdir
23024
23025         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23026
23027         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23028
23029         cancel_lru_locks mdc
23030         dd if=/dev/urandom of=$tmp bs=1000 count=1
23031         dd if=$tmp of=$dom bs=1000 count=1
23032         cancel_lru_locks mdc
23033
23034         cat /etc/hosts >> $tmp
23035         lctl set_param -n mdc.*.stats=clear
23036
23037         # append data to the same file it should update local page
23038         echo "Append to the same page"
23039         cat /etc/hosts >> $dom
23040         local num=$(get_mdc_stats $mdtidx ost_read)
23041         local ra=$(get_mdc_stats $mdtidx req_active)
23042         local rw=$(get_mdc_stats $mdtidx req_waittime)
23043
23044         [ -z $num ] || error "$num READ RPC occured"
23045         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23046         echo "... DONE"
23047
23048         # compare content
23049         cmp $tmp $dom || error "file miscompare"
23050
23051         cancel_lru_locks mdc
23052         lctl set_param -n mdc.*.stats=clear
23053
23054         echo "Open and read file"
23055         cat $dom > /dev/null
23056         local num=$(get_mdc_stats $mdtidx ost_read)
23057         local ra=$(get_mdc_stats $mdtidx req_active)
23058         local rw=$(get_mdc_stats $mdtidx req_waittime)
23059
23060         [ -z $num ] || error "$num READ RPC occured"
23061         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23062         echo "... DONE"
23063
23064         # compare content
23065         cmp $tmp $dom || error "file miscompare"
23066
23067         return 0
23068 }
23069 run_test 271d "DoM: read on open (1K file in reply buffer)"
23070
23071 test_271f() {
23072         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23073                 skip "Need MDS version at least 2.10.57"
23074
23075         local dom=$DIR/$tdir/dom
23076         local tmp=$TMP/$tfile
23077         trap "cleanup_271def_tests $tmp" EXIT
23078
23079         mkdir -p $DIR/$tdir
23080
23081         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23082
23083         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23084
23085         cancel_lru_locks mdc
23086         dd if=/dev/urandom of=$tmp bs=265000 count=1
23087         dd if=$tmp of=$dom bs=265000 count=1
23088         cancel_lru_locks mdc
23089         cat /etc/hosts >> $tmp
23090         lctl set_param -n mdc.*.stats=clear
23091
23092         echo "Append to the same page"
23093         cat /etc/hosts >> $dom
23094         local num=$(get_mdc_stats $mdtidx ost_read)
23095         local ra=$(get_mdc_stats $mdtidx req_active)
23096         local rw=$(get_mdc_stats $mdtidx req_waittime)
23097
23098         [ -z $num ] || error "$num READ RPC occured"
23099         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23100         echo "... DONE"
23101
23102         # compare content
23103         cmp $tmp $dom || error "file miscompare"
23104
23105         cancel_lru_locks mdc
23106         lctl set_param -n mdc.*.stats=clear
23107
23108         echo "Open and read file"
23109         cat $dom > /dev/null
23110         local num=$(get_mdc_stats $mdtidx ost_read)
23111         local ra=$(get_mdc_stats $mdtidx req_active)
23112         local rw=$(get_mdc_stats $mdtidx req_waittime)
23113
23114         [ -z $num ] && num=0
23115         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23116         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23117         echo "... DONE"
23118
23119         # compare content
23120         cmp $tmp $dom || error "file miscompare"
23121
23122         return 0
23123 }
23124 run_test 271f "DoM: read on open (200K file and read tail)"
23125
23126 test_271g() {
23127         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23128                 skip "Skipping due to old client or server version"
23129
23130         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23131         # to get layout
23132         $CHECKSTAT -t file $DIR1/$tfile
23133
23134         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23135         MULTIOP_PID=$!
23136         sleep 1
23137         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23138         $LCTL set_param fail_loc=0x80000314
23139         rm $DIR1/$tfile || error "Unlink fails"
23140         RC=$?
23141         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23142         [ $RC -eq 0 ] || error "Failed write to stale object"
23143 }
23144 run_test 271g "Discard DoM data vs client flush race"
23145
23146 test_272a() {
23147         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23148                 skip "Need MDS version at least 2.11.50"
23149
23150         local dom=$DIR/$tdir/dom
23151         mkdir -p $DIR/$tdir
23152
23153         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23154         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23155                 error "failed to write data into $dom"
23156         local old_md5=$(md5sum $dom)
23157
23158         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23159                 error "failed to migrate to the same DoM component"
23160
23161         local new_md5=$(md5sum $dom)
23162
23163         [ "$old_md5" == "$new_md5" ] ||
23164                 error "md5sum differ: $old_md5, $new_md5"
23165
23166         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23167                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23168 }
23169 run_test 272a "DoM migration: new layout with the same DOM component"
23170
23171 test_272b() {
23172         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23173                 skip "Need MDS version at least 2.11.50"
23174
23175         local dom=$DIR/$tdir/dom
23176         mkdir -p $DIR/$tdir
23177         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23178
23179         local mdtidx=$($LFS getstripe -m $dom)
23180         local mdtname=MDT$(printf %04x $mdtidx)
23181         local facet=mds$((mdtidx + 1))
23182
23183         local mdtfree1=$(do_facet $facet \
23184                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23185         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23186                 error "failed to write data into $dom"
23187         local old_md5=$(md5sum $dom)
23188         cancel_lru_locks mdc
23189         local mdtfree1=$(do_facet $facet \
23190                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23191
23192         $LFS migrate -c2 $dom ||
23193                 error "failed to migrate to the new composite layout"
23194         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23195                 error "MDT stripe was not removed"
23196
23197         cancel_lru_locks mdc
23198         local new_md5=$(md5sum $dom)
23199         [ "$old_md5" == "$new_md5" ] ||
23200                 error "$old_md5 != $new_md5"
23201
23202         # Skip free space checks with ZFS
23203         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23204                 local mdtfree2=$(do_facet $facet \
23205                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23206                 [ $mdtfree2 -gt $mdtfree1 ] ||
23207                         error "MDT space is not freed after migration"
23208         fi
23209         return 0
23210 }
23211 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23212
23213 test_272c() {
23214         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23215                 skip "Need MDS version at least 2.11.50"
23216
23217         local dom=$DIR/$tdir/$tfile
23218         mkdir -p $DIR/$tdir
23219         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23220
23221         local mdtidx=$($LFS getstripe -m $dom)
23222         local mdtname=MDT$(printf %04x $mdtidx)
23223         local facet=mds$((mdtidx + 1))
23224
23225         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23226                 error "failed to write data into $dom"
23227         local old_md5=$(md5sum $dom)
23228         cancel_lru_locks mdc
23229         local mdtfree1=$(do_facet $facet \
23230                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23231
23232         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23233                 error "failed to migrate to the new composite layout"
23234         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23235                 error "MDT stripe was not removed"
23236
23237         cancel_lru_locks mdc
23238         local new_md5=$(md5sum $dom)
23239         [ "$old_md5" == "$new_md5" ] ||
23240                 error "$old_md5 != $new_md5"
23241
23242         # Skip free space checks with ZFS
23243         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23244                 local mdtfree2=$(do_facet $facet \
23245                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23246                 [ $mdtfree2 -gt $mdtfree1 ] ||
23247                         error "MDS space is not freed after migration"
23248         fi
23249         return 0
23250 }
23251 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23252
23253 test_272d() {
23254         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23255                 skip "Need MDS version at least 2.12.55"
23256
23257         local dom=$DIR/$tdir/$tfile
23258         mkdir -p $DIR/$tdir
23259         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23260
23261         local mdtidx=$($LFS getstripe -m $dom)
23262         local mdtname=MDT$(printf %04x $mdtidx)
23263         local facet=mds$((mdtidx + 1))
23264
23265         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23266                 error "failed to write data into $dom"
23267         local old_md5=$(md5sum $dom)
23268         cancel_lru_locks mdc
23269         local mdtfree1=$(do_facet $facet \
23270                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23271
23272         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23273                 error "failed mirroring to the new composite layout"
23274         $LFS mirror resync $dom ||
23275                 error "failed mirror resync"
23276         $LFS mirror split --mirror-id 1 -d $dom ||
23277                 error "failed mirror split"
23278
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 "MDS space is not freed after DOM mirror deletion"
23293         fi
23294         return 0
23295 }
23296 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23297
23298 test_272e() {
23299         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23300                 skip "Need MDS version at least 2.12.55"
23301
23302         local dom=$DIR/$tdir/$tfile
23303         mkdir -p $DIR/$tdir
23304         $LFS setstripe -c 2 $dom
23305
23306         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23307                 error "failed to write data into $dom"
23308         local old_md5=$(md5sum $dom)
23309         cancel_lru_locks
23310
23311         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23312                 error "failed mirroring to the DOM layout"
23313         $LFS mirror resync $dom ||
23314                 error "failed mirror resync"
23315         $LFS mirror split --mirror-id 1 -d $dom ||
23316                 error "failed mirror split"
23317
23318         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23319                 error "MDT stripe wasn't set"
23320
23321         cancel_lru_locks
23322         local new_md5=$(md5sum $dom)
23323         [ "$old_md5" == "$new_md5" ] ||
23324                 error "$old_md5 != $new_md5"
23325
23326         return 0
23327 }
23328 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23329
23330 test_272f() {
23331         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23332                 skip "Need MDS version at least 2.12.55"
23333
23334         local dom=$DIR/$tdir/$tfile
23335         mkdir -p $DIR/$tdir
23336         $LFS setstripe -c 2 $dom
23337
23338         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23339                 error "failed to write data into $dom"
23340         local old_md5=$(md5sum $dom)
23341         cancel_lru_locks
23342
23343         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23344                 error "failed migrating to the DOM file"
23345
23346         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23347                 error "MDT stripe wasn't set"
23348
23349         cancel_lru_locks
23350         local new_md5=$(md5sum $dom)
23351         [ "$old_md5" != "$new_md5" ] &&
23352                 error "$old_md5 != $new_md5"
23353
23354         return 0
23355 }
23356 run_test 272f "DoM migration: OST-striped file to DOM file"
23357
23358 test_273a() {
23359         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23360                 skip "Need MDS version at least 2.11.50"
23361
23362         # Layout swap cannot be done if either file has DOM component,
23363         # this will never be supported, migration should be used instead
23364
23365         local dom=$DIR/$tdir/$tfile
23366         mkdir -p $DIR/$tdir
23367
23368         $LFS setstripe -c2 ${dom}_plain
23369         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23370         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23371                 error "can swap layout with DoM component"
23372         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23373                 error "can swap layout with DoM component"
23374
23375         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23376         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23377                 error "can swap layout with DoM component"
23378         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23379                 error "can swap layout with DoM component"
23380         return 0
23381 }
23382 run_test 273a "DoM: layout swapping should fail with DOM"
23383
23384 test_273b() {
23385         mkdir -p $DIR/$tdir
23386         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23387
23388 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23389         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23390
23391         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23392 }
23393 run_test 273b "DoM: race writeback and object destroy"
23394
23395 test_275() {
23396         remote_ost_nodsh && skip "remote OST with nodsh"
23397         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23398                 skip "Need OST version >= 2.10.57"
23399
23400         local file=$DIR/$tfile
23401         local oss
23402
23403         oss=$(comma_list $(osts_nodes))
23404
23405         dd if=/dev/urandom of=$file bs=1M count=2 ||
23406                 error "failed to create a file"
23407         cancel_lru_locks osc
23408
23409         #lock 1
23410         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23411                 error "failed to read a file"
23412
23413 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23414         $LCTL set_param fail_loc=0x8000031f
23415
23416         cancel_lru_locks osc &
23417         sleep 1
23418
23419 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23420         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23421         #IO takes another lock, but matches the PENDING one
23422         #and places it to the IO RPC
23423         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23424                 error "failed to read a file with PENDING lock"
23425 }
23426 run_test 275 "Read on a canceled duplicate lock"
23427
23428 test_276() {
23429         remote_ost_nodsh && skip "remote OST with nodsh"
23430         local pid
23431
23432         do_facet ost1 "(while true; do \
23433                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23434                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23435         pid=$!
23436
23437         for LOOP in $(seq 20); do
23438                 stop ost1
23439                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23440         done
23441         kill -9 $pid
23442         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23443                 rm $TMP/sanity_276_pid"
23444 }
23445 run_test 276 "Race between mount and obd_statfs"
23446
23447 test_277() {
23448         $LCTL set_param ldlm.namespaces.*.lru_size=0
23449         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23450         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23451                         grep ^used_mb | awk '{print $2}')
23452         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23453         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23454                 oflag=direct conv=notrunc
23455         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23456                         grep ^used_mb | awk '{print $2}')
23457         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23458 }
23459 run_test 277 "Direct IO shall drop page cache"
23460
23461 test_278() {
23462         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23464         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23465                 skip "needs the same host for mdt1 mdt2" && return
23466
23467         local pid1
23468         local pid2
23469
23470 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23471         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23472         stop mds2 &
23473         pid2=$!
23474
23475         stop mds1
23476
23477         echo "Starting MDTs"
23478         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23479         wait $pid2
23480 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23481 #will return NULL
23482         do_facet mds2 $LCTL set_param fail_loc=0
23483
23484         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23485         wait_recovery_complete mds2
23486 }
23487 run_test 278 "Race starting MDS between MDTs stop/start"
23488
23489 test_280() {
23490         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23491                 skip "Need MGS version at least 2.13.52"
23492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23493         combined_mgs_mds || skip "needs combined MGS/MDT"
23494
23495         umount_client $MOUNT
23496 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23497         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23498
23499         mount_client $MOUNT &
23500         sleep 1
23501         stop mgs || error "stop mgs failed"
23502         #for a race mgs would crash
23503         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23504         # make sure we unmount client before remounting
23505         wait
23506         umount_client $MOUNT
23507         mount_client $MOUNT || error "mount client failed"
23508 }
23509 run_test 280 "Race between MGS umount and client llog processing"
23510
23511 cleanup_test_300() {
23512         trap 0
23513         umask $SAVE_UMASK
23514 }
23515 test_striped_dir() {
23516         local mdt_index=$1
23517         local stripe_count
23518         local stripe_index
23519
23520         mkdir -p $DIR/$tdir
23521
23522         SAVE_UMASK=$(umask)
23523         trap cleanup_test_300 RETURN EXIT
23524
23525         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23526                                                 $DIR/$tdir/striped_dir ||
23527                 error "set striped dir error"
23528
23529         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23530         [ "$mode" = "755" ] || error "expect 755 got $mode"
23531
23532         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23533                 error "getdirstripe failed"
23534         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23535         if [ "$stripe_count" != "2" ]; then
23536                 error "1:stripe_count is $stripe_count, expect 2"
23537         fi
23538         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23539         if [ "$stripe_count" != "2" ]; then
23540                 error "2:stripe_count is $stripe_count, expect 2"
23541         fi
23542
23543         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23544         if [ "$stripe_index" != "$mdt_index" ]; then
23545                 error "stripe_index is $stripe_index, expect $mdt_index"
23546         fi
23547
23548         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23549                 error "nlink error after create striped dir"
23550
23551         mkdir $DIR/$tdir/striped_dir/a
23552         mkdir $DIR/$tdir/striped_dir/b
23553
23554         stat $DIR/$tdir/striped_dir/a ||
23555                 error "create dir under striped dir failed"
23556         stat $DIR/$tdir/striped_dir/b ||
23557                 error "create dir under striped dir failed"
23558
23559         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23560                 error "nlink error after mkdir"
23561
23562         rmdir $DIR/$tdir/striped_dir/a
23563         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23564                 error "nlink error after rmdir"
23565
23566         rmdir $DIR/$tdir/striped_dir/b
23567         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23568                 error "nlink error after rmdir"
23569
23570         chattr +i $DIR/$tdir/striped_dir
23571         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23572                 error "immutable flags not working under striped dir!"
23573         chattr -i $DIR/$tdir/striped_dir
23574
23575         rmdir $DIR/$tdir/striped_dir ||
23576                 error "rmdir striped dir error"
23577
23578         cleanup_test_300
23579
23580         true
23581 }
23582
23583 test_300a() {
23584         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23585                 skip "skipped for lustre < 2.7.0"
23586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23588
23589         test_striped_dir 0 || error "failed on striped dir on MDT0"
23590         test_striped_dir 1 || error "failed on striped dir on MDT0"
23591 }
23592 run_test 300a "basic striped dir sanity test"
23593
23594 test_300b() {
23595         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23596                 skip "skipped for lustre < 2.7.0"
23597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23599
23600         local i
23601         local mtime1
23602         local mtime2
23603         local mtime3
23604
23605         test_mkdir $DIR/$tdir || error "mkdir fail"
23606         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23607                 error "set striped dir error"
23608         for i in {0..9}; do
23609                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23610                 sleep 1
23611                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23612                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23613                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23614                 sleep 1
23615                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23616                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23617                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23618         done
23619         true
23620 }
23621 run_test 300b "check ctime/mtime for striped dir"
23622
23623 test_300c() {
23624         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23625                 skip "skipped for lustre < 2.7.0"
23626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23628
23629         local file_count
23630
23631         mkdir_on_mdt0 $DIR/$tdir
23632         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23633                 error "set striped dir error"
23634
23635         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23636                 error "chown striped dir failed"
23637
23638         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23639                 error "create 5k files failed"
23640
23641         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23642
23643         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23644
23645         rm -rf $DIR/$tdir
23646 }
23647 run_test 300c "chown && check ls under striped directory"
23648
23649 test_300d() {
23650         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23651                 skip "skipped for lustre < 2.7.0"
23652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23654
23655         local stripe_count
23656         local file
23657
23658         mkdir -p $DIR/$tdir
23659         $LFS setstripe -c 2 $DIR/$tdir
23660
23661         #local striped directory
23662         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23663                 error "set striped dir error"
23664         #look at the directories for debug purposes
23665         ls -l $DIR/$tdir
23666         $LFS getdirstripe $DIR/$tdir
23667         ls -l $DIR/$tdir/striped_dir
23668         $LFS getdirstripe $DIR/$tdir/striped_dir
23669         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23670                 error "create 10 files failed"
23671
23672         #remote striped directory
23673         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23674                 error "set striped dir error"
23675         #look at the directories for debug purposes
23676         ls -l $DIR/$tdir
23677         $LFS getdirstripe $DIR/$tdir
23678         ls -l $DIR/$tdir/remote_striped_dir
23679         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23680         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23681                 error "create 10 files failed"
23682
23683         for file in $(find $DIR/$tdir); do
23684                 stripe_count=$($LFS getstripe -c $file)
23685                 [ $stripe_count -eq 2 ] ||
23686                         error "wrong stripe $stripe_count for $file"
23687         done
23688
23689         rm -rf $DIR/$tdir
23690 }
23691 run_test 300d "check default stripe under striped directory"
23692
23693 test_300e() {
23694         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23695                 skip "Need MDS version at least 2.7.55"
23696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23698
23699         local stripe_count
23700         local file
23701
23702         mkdir -p $DIR/$tdir
23703
23704         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23705                 error "set striped dir error"
23706
23707         touch $DIR/$tdir/striped_dir/a
23708         touch $DIR/$tdir/striped_dir/b
23709         touch $DIR/$tdir/striped_dir/c
23710
23711         mkdir $DIR/$tdir/striped_dir/dir_a
23712         mkdir $DIR/$tdir/striped_dir/dir_b
23713         mkdir $DIR/$tdir/striped_dir/dir_c
23714
23715         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23716                 error "set striped adir under striped dir error"
23717
23718         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23719                 error "set striped bdir under striped dir error"
23720
23721         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23722                 error "set striped cdir under striped dir error"
23723
23724         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23725                 error "rename dir under striped dir fails"
23726
23727         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23728                 error "rename dir under different stripes fails"
23729
23730         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23731                 error "rename file under striped dir should succeed"
23732
23733         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23734                 error "rename dir under striped dir should succeed"
23735
23736         rm -rf $DIR/$tdir
23737 }
23738 run_test 300e "check rename under striped directory"
23739
23740 test_300f() {
23741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23743         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23744                 skip "Need MDS version at least 2.7.55"
23745
23746         local stripe_count
23747         local file
23748
23749         rm -rf $DIR/$tdir
23750         mkdir -p $DIR/$tdir
23751
23752         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23753                 error "set striped dir error"
23754
23755         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23756                 error "set striped dir error"
23757
23758         touch $DIR/$tdir/striped_dir/a
23759         mkdir $DIR/$tdir/striped_dir/dir_a
23760         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23761                 error "create striped dir under striped dir fails"
23762
23763         touch $DIR/$tdir/striped_dir1/b
23764         mkdir $DIR/$tdir/striped_dir1/dir_b
23765         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23766                 error "create striped dir under striped dir fails"
23767
23768         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23769                 error "rename dir under different striped dir should fail"
23770
23771         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23772                 error "rename striped dir under diff striped dir should fail"
23773
23774         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23775                 error "rename file under diff striped dirs fails"
23776
23777         rm -rf $DIR/$tdir
23778 }
23779 run_test 300f "check rename cross striped directory"
23780
23781 test_300_check_default_striped_dir()
23782 {
23783         local dirname=$1
23784         local default_count=$2
23785         local default_index=$3
23786         local stripe_count
23787         local stripe_index
23788         local dir_stripe_index
23789         local dir
23790
23791         echo "checking $dirname $default_count $default_index"
23792         $LFS setdirstripe -D -c $default_count -i $default_index \
23793                                 -H all_char $DIR/$tdir/$dirname ||
23794                 error "set default stripe on striped dir error"
23795         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23796         [ $stripe_count -eq $default_count ] ||
23797                 error "expect $default_count get $stripe_count for $dirname"
23798
23799         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23800         [ $stripe_index -eq $default_index ] ||
23801                 error "expect $default_index get $stripe_index for $dirname"
23802
23803         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23804                                                 error "create dirs failed"
23805
23806         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23807         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23808         for dir in $(find $DIR/$tdir/$dirname/*); do
23809                 stripe_count=$($LFS getdirstripe -c $dir)
23810                 (( $stripe_count == $default_count )) ||
23811                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23812                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23813                 error "stripe count $default_count != $stripe_count for $dir"
23814
23815                 stripe_index=$($LFS getdirstripe -i $dir)
23816                 [ $default_index -eq -1 ] ||
23817                         [ $stripe_index -eq $default_index ] ||
23818                         error "$stripe_index != $default_index for $dir"
23819
23820                 #check default stripe
23821                 stripe_count=$($LFS getdirstripe -D -c $dir)
23822                 [ $stripe_count -eq $default_count ] ||
23823                 error "default count $default_count != $stripe_count for $dir"
23824
23825                 stripe_index=$($LFS getdirstripe -D -i $dir)
23826                 [ $stripe_index -eq $default_index ] ||
23827                 error "default index $default_index != $stripe_index for $dir"
23828         done
23829         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23830 }
23831
23832 test_300g() {
23833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23834         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23835                 skip "Need MDS version at least 2.7.55"
23836
23837         local dir
23838         local stripe_count
23839         local stripe_index
23840
23841         mkdir_on_mdt0 $DIR/$tdir
23842         mkdir $DIR/$tdir/normal_dir
23843
23844         #Checking when client cache stripe index
23845         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23846         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23847                 error "create striped_dir failed"
23848
23849         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23850                 error "create dir0 fails"
23851         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23852         [ $stripe_index -eq 0 ] ||
23853                 error "dir0 expect index 0 got $stripe_index"
23854
23855         mkdir $DIR/$tdir/striped_dir/dir1 ||
23856                 error "create dir1 fails"
23857         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23858         [ $stripe_index -eq 1 ] ||
23859                 error "dir1 expect index 1 got $stripe_index"
23860
23861         #check default stripe count/stripe index
23862         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23863         test_300_check_default_striped_dir normal_dir 1 0
23864         test_300_check_default_striped_dir normal_dir -1 1
23865         test_300_check_default_striped_dir normal_dir 2 -1
23866
23867         #delete default stripe information
23868         echo "delete default stripeEA"
23869         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23870                 error "set default stripe on striped dir error"
23871
23872         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23873         for dir in $(find $DIR/$tdir/normal_dir/*); do
23874                 stripe_count=$($LFS getdirstripe -c $dir)
23875                 [ $stripe_count -eq 0 ] ||
23876                         error "expect 1 get $stripe_count for $dir"
23877         done
23878 }
23879 run_test 300g "check default striped directory for normal directory"
23880
23881 test_300h() {
23882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23883         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23884                 skip "Need MDS version at least 2.7.55"
23885
23886         local dir
23887         local stripe_count
23888
23889         mkdir $DIR/$tdir
23890         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23891                 error "set striped dir error"
23892
23893         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23894         test_300_check_default_striped_dir striped_dir 1 0
23895         test_300_check_default_striped_dir striped_dir -1 1
23896         test_300_check_default_striped_dir striped_dir 2 -1
23897
23898         #delete default stripe information
23899         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23900                 error "set default stripe on striped dir error"
23901
23902         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23903         for dir in $(find $DIR/$tdir/striped_dir/*); do
23904                 stripe_count=$($LFS getdirstripe -c $dir)
23905                 [ $stripe_count -eq 0 ] ||
23906                         error "expect 1 get $stripe_count for $dir"
23907         done
23908 }
23909 run_test 300h "check default striped directory for striped directory"
23910
23911 test_300i() {
23912         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23913         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23914         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23915                 skip "Need MDS version at least 2.7.55"
23916
23917         local stripe_count
23918         local file
23919
23920         mkdir $DIR/$tdir
23921
23922         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23923                 error "set striped dir error"
23924
23925         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23926                 error "create files under striped dir failed"
23927
23928         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23929                 error "set striped hashdir error"
23930
23931         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23932                 error "create dir0 under hash dir failed"
23933         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23934                 error "create dir1 under hash dir failed"
23935         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23936                 error "create dir2 under hash dir failed"
23937
23938         # unfortunately, we need to umount to clear dir layout cache for now
23939         # once we fully implement dir layout, we can drop this
23940         umount_client $MOUNT || error "umount failed"
23941         mount_client $MOUNT || error "mount failed"
23942
23943         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23944         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23945         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23946
23947         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23948                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23949                         error "create crush2 dir $tdir/hashdir/d3 failed"
23950                 $LFS find -H crush2 $DIR/$tdir/hashdir
23951                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23952                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23953
23954                 # mkdir with an invalid hash type (hash=fail_val) from client
23955                 # should be replaced on MDS with a valid (default) hash type
23956                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23957                 $LCTL set_param fail_loc=0x1901 fail_val=99
23958                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23959
23960                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23961                 local expect=$(do_facet mds1 \
23962                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23963                 [[ $hash == $expect ]] ||
23964                         error "d99 hash '$hash' != expected hash '$expect'"
23965         fi
23966
23967         #set the stripe to be unknown hash type on read
23968         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23969         $LCTL set_param fail_loc=0x1901 fail_val=99
23970         for ((i = 0; i < 10; i++)); do
23971                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23972                         error "stat f-$i failed"
23973                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23974         done
23975
23976         touch $DIR/$tdir/striped_dir/f0 &&
23977                 error "create under striped dir with unknown hash should fail"
23978
23979         $LCTL set_param fail_loc=0
23980
23981         umount_client $MOUNT || error "umount failed"
23982         mount_client $MOUNT || error "mount failed"
23983
23984         return 0
23985 }
23986 run_test 300i "client handle unknown hash type striped directory"
23987
23988 test_300j() {
23989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23991         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23992                 skip "Need MDS version at least 2.7.55"
23993
23994         local stripe_count
23995         local file
23996
23997         mkdir $DIR/$tdir
23998
23999         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24000         $LCTL set_param fail_loc=0x1702
24001         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24002                 error "set striped dir error"
24003
24004         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24005                 error "create files under striped dir failed"
24006
24007         $LCTL set_param fail_loc=0
24008
24009         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24010
24011         return 0
24012 }
24013 run_test 300j "test large update record"
24014
24015 test_300k() {
24016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24018         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24019                 skip "Need MDS version at least 2.7.55"
24020
24021         # this test needs a huge transaction
24022         local kb
24023         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24024              osd*.$FSNAME-MDT0000.kbytestotal")
24025         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24026
24027         local stripe_count
24028         local file
24029
24030         mkdir $DIR/$tdir
24031
24032         #define OBD_FAIL_LARGE_STRIPE   0x1703
24033         $LCTL set_param fail_loc=0x1703
24034         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24035                 error "set striped dir error"
24036         $LCTL set_param fail_loc=0
24037
24038         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24039                 error "getstripeddir fails"
24040         rm -rf $DIR/$tdir/striped_dir ||
24041                 error "unlink striped dir fails"
24042
24043         return 0
24044 }
24045 run_test 300k "test large striped directory"
24046
24047 test_300l() {
24048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24050         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24051                 skip "Need MDS version at least 2.7.55"
24052
24053         local stripe_index
24054
24055         test_mkdir -p $DIR/$tdir/striped_dir
24056         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24057                         error "chown $RUNAS_ID failed"
24058         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24059                 error "set default striped dir failed"
24060
24061         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24062         $LCTL set_param fail_loc=0x80000158
24063         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24064
24065         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24066         [ $stripe_index -eq 1 ] ||
24067                 error "expect 1 get $stripe_index for $dir"
24068 }
24069 run_test 300l "non-root user to create dir under striped dir with stale layout"
24070
24071 test_300m() {
24072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24073         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24074         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24075                 skip "Need MDS version at least 2.7.55"
24076
24077         mkdir -p $DIR/$tdir/striped_dir
24078         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24079                 error "set default stripes dir error"
24080
24081         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24082
24083         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24084         [ $stripe_count -eq 0 ] ||
24085                         error "expect 0 get $stripe_count for a"
24086
24087         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24088                 error "set default stripes dir error"
24089
24090         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24091
24092         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24093         [ $stripe_count -eq 0 ] ||
24094                         error "expect 0 get $stripe_count for b"
24095
24096         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24097                 error "set default stripes dir error"
24098
24099         mkdir $DIR/$tdir/striped_dir/c &&
24100                 error "default stripe_index is invalid, mkdir c should fails"
24101
24102         rm -rf $DIR/$tdir || error "rmdir fails"
24103 }
24104 run_test 300m "setstriped directory on single MDT FS"
24105
24106 cleanup_300n() {
24107         local list=$(comma_list $(mdts_nodes))
24108
24109         trap 0
24110         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24111 }
24112
24113 test_300n() {
24114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24116         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24117                 skip "Need MDS version at least 2.7.55"
24118         remote_mds_nodsh && skip "remote MDS with nodsh"
24119
24120         local stripe_index
24121         local list=$(comma_list $(mdts_nodes))
24122
24123         trap cleanup_300n RETURN EXIT
24124         mkdir -p $DIR/$tdir
24125         chmod 777 $DIR/$tdir
24126         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24127                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24128                 error "create striped dir succeeds with gid=0"
24129
24130         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24131         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24132                 error "create striped dir fails with gid=-1"
24133
24134         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24135         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24136                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24137                 error "set default striped dir succeeds with gid=0"
24138
24139
24140         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24141         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24142                 error "set default striped dir fails with gid=-1"
24143
24144
24145         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24146         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24147                                         error "create test_dir fails"
24148         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24149                                         error "create test_dir1 fails"
24150         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24151                                         error "create test_dir2 fails"
24152         cleanup_300n
24153 }
24154 run_test 300n "non-root user to create dir under striped dir with default EA"
24155
24156 test_300o() {
24157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24159         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24160                 skip "Need MDS version at least 2.7.55"
24161
24162         local numfree1
24163         local numfree2
24164
24165         mkdir -p $DIR/$tdir
24166
24167         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24168         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24169         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24170                 skip "not enough free inodes $numfree1 $numfree2"
24171         fi
24172
24173         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24174         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24175         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24176                 skip "not enough free space $numfree1 $numfree2"
24177         fi
24178
24179         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24180                 error "setdirstripe fails"
24181
24182         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24183                 error "create dirs fails"
24184
24185         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24186         ls $DIR/$tdir/striped_dir > /dev/null ||
24187                 error "ls striped dir fails"
24188         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24189                 error "unlink big striped dir fails"
24190 }
24191 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24192
24193 test_300p() {
24194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24196         remote_mds_nodsh && skip "remote MDS with nodsh"
24197
24198         mkdir_on_mdt0 $DIR/$tdir
24199
24200         #define OBD_FAIL_OUT_ENOSPC     0x1704
24201         do_facet mds2 lctl set_param fail_loc=0x80001704
24202         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24203                  && error "create striped directory should fail"
24204
24205         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24206
24207         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24208         true
24209 }
24210 run_test 300p "create striped directory without space"
24211
24212 test_300q() {
24213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24214         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24215
24216         local fd=$(free_fd)
24217         local cmd="exec $fd<$tdir"
24218         cd $DIR
24219         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24220         eval $cmd
24221         cmd="exec $fd<&-"
24222         trap "eval $cmd" EXIT
24223         cd $tdir || error "cd $tdir fails"
24224         rmdir  ../$tdir || error "rmdir $tdir fails"
24225         mkdir local_dir && error "create dir succeeds"
24226         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24227         eval $cmd
24228         return 0
24229 }
24230 run_test 300q "create remote directory under orphan directory"
24231
24232 test_300r() {
24233         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24234                 skip "Need MDS version at least 2.7.55" && return
24235         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24236
24237         mkdir $DIR/$tdir
24238
24239         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24240                 error "set striped dir error"
24241
24242         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24243                 error "getstripeddir fails"
24244
24245         local stripe_count
24246         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24247                       awk '/lmv_stripe_count:/ { print $2 }')
24248
24249         [ $MDSCOUNT -ne $stripe_count ] &&
24250                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24251
24252         rm -rf $DIR/$tdir/striped_dir ||
24253                 error "unlink striped dir fails"
24254 }
24255 run_test 300r "test -1 striped directory"
24256
24257 test_300s_helper() {
24258         local count=$1
24259
24260         local stripe_dir=$DIR/$tdir/striped_dir.$count
24261
24262         $LFS mkdir -c $count $stripe_dir ||
24263                 error "lfs mkdir -c error"
24264
24265         $LFS getdirstripe $stripe_dir ||
24266                 error "lfs getdirstripe fails"
24267
24268         local stripe_count
24269         stripe_count=$($LFS getdirstripe $stripe_dir |
24270                       awk '/lmv_stripe_count:/ { print $2 }')
24271
24272         [ $count -ne $stripe_count ] &&
24273                 error_noexit "bad stripe count $stripe_count expected $count"
24274
24275         local dupe_stripes
24276         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24277                 awk '/0x/ {count[$1] += 1}; END {
24278                         for (idx in count) {
24279                                 if (count[idx]>1) {
24280                                         print "index " idx " count " count[idx]
24281                                 }
24282                         }
24283                 }')
24284
24285         if [[ -n "$dupe_stripes" ]] ; then
24286                 lfs getdirstripe $stripe_dir
24287                 error_noexit "Dupe MDT above: $dupe_stripes "
24288         fi
24289
24290         rm -rf $stripe_dir ||
24291                 error_noexit "unlink $stripe_dir fails"
24292 }
24293
24294 test_300s() {
24295         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24296                 skip "Need MDS version at least 2.7.55" && return
24297         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24298
24299         mkdir $DIR/$tdir
24300         for count in $(seq 2 $MDSCOUNT); do
24301                 test_300s_helper $count
24302         done
24303 }
24304 run_test 300s "test lfs mkdir -c without -i"
24305
24306 test_300t() {
24307         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24308                 skip "need MDS 2.14.55 or later"
24309         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24310
24311         local testdir="$DIR/$tdir/striped_dir"
24312         local dir1=$testdir/dir1
24313         local dir2=$testdir/dir2
24314
24315         mkdir -p $testdir
24316
24317         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24318                 error "failed to set default stripe count for $testdir"
24319
24320         mkdir $dir1
24321         local stripe_count=$($LFS getdirstripe -c $dir1)
24322
24323         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24324
24325         local max_count=$((MDSCOUNT - 1))
24326         local mdts=$(comma_list $(mdts_nodes))
24327
24328         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24329         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24330
24331         mkdir $dir2
24332         stripe_count=$($LFS getdirstripe -c $dir2)
24333
24334         (( $stripe_count == $max_count )) || error "wrong stripe count"
24335 }
24336 run_test 300t "test max_mdt_stripecount"
24337
24338 prepare_remote_file() {
24339         mkdir $DIR/$tdir/src_dir ||
24340                 error "create remote source failed"
24341
24342         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24343                  error "cp to remote source failed"
24344         touch $DIR/$tdir/src_dir/a
24345
24346         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24347                 error "create remote target dir failed"
24348
24349         touch $DIR/$tdir/tgt_dir/b
24350
24351         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24352                 error "rename dir cross MDT failed!"
24353
24354         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24355                 error "src_child still exists after rename"
24356
24357         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24358                 error "missing file(a) after rename"
24359
24360         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24361                 error "diff after rename"
24362 }
24363
24364 test_310a() {
24365         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24367
24368         local remote_file=$DIR/$tdir/tgt_dir/b
24369
24370         mkdir -p $DIR/$tdir
24371
24372         prepare_remote_file || error "prepare remote file failed"
24373
24374         #open-unlink file
24375         $OPENUNLINK $remote_file $remote_file ||
24376                 error "openunlink $remote_file failed"
24377         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24378 }
24379 run_test 310a "open unlink remote file"
24380
24381 test_310b() {
24382         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24384
24385         local remote_file=$DIR/$tdir/tgt_dir/b
24386
24387         mkdir -p $DIR/$tdir
24388
24389         prepare_remote_file || error "prepare remote file failed"
24390
24391         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24392         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24393         $CHECKSTAT -t file $remote_file || error "check file failed"
24394 }
24395 run_test 310b "unlink remote file with multiple links while open"
24396
24397 test_310c() {
24398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24399         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24400
24401         local remote_file=$DIR/$tdir/tgt_dir/b
24402
24403         mkdir -p $DIR/$tdir
24404
24405         prepare_remote_file || error "prepare remote file failed"
24406
24407         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24408         multiop_bg_pause $remote_file O_uc ||
24409                         error "mulitop failed for remote file"
24410         MULTIPID=$!
24411         $MULTIOP $DIR/$tfile Ouc
24412         kill -USR1 $MULTIPID
24413         wait $MULTIPID
24414 }
24415 run_test 310c "open-unlink remote file with multiple links"
24416
24417 #LU-4825
24418 test_311() {
24419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24420         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24421         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24422                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24423         remote_mds_nodsh && skip "remote MDS with nodsh"
24424
24425         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24426         local mdts=$(comma_list $(mdts_nodes))
24427
24428         mkdir -p $DIR/$tdir
24429         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24430         createmany -o $DIR/$tdir/$tfile. 1000
24431
24432         # statfs data is not real time, let's just calculate it
24433         old_iused=$((old_iused + 1000))
24434
24435         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24436                         osp.*OST0000*MDT0000.create_count")
24437         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24438                                 osp.*OST0000*MDT0000.max_create_count")
24439         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24440
24441         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24442         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24443         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24444
24445         unlinkmany $DIR/$tdir/$tfile. 1000
24446
24447         do_nodes $mdts "$LCTL set_param -n \
24448                         osp.*OST0000*.max_create_count=$max_count"
24449         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24450                 do_nodes $mdts "$LCTL set_param -n \
24451                                 osp.*OST0000*.create_count=$count"
24452         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24453                         grep "=0" && error "create_count is zero"
24454
24455         local new_iused
24456         for i in $(seq 120); do
24457                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24458                 # system may be too busy to destroy all objs in time, use
24459                 # a somewhat small value to not fail autotest
24460                 [ $((old_iused - new_iused)) -gt 400 ] && break
24461                 sleep 1
24462         done
24463
24464         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24465         [ $((old_iused - new_iused)) -gt 400 ] ||
24466                 error "objs not destroyed after unlink"
24467 }
24468 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24469
24470 zfs_oid_to_objid()
24471 {
24472         local ost=$1
24473         local objid=$2
24474
24475         local vdevdir=$(dirname $(facet_vdevice $ost))
24476         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24477         local zfs_zapid=$(do_facet $ost $cmd |
24478                           grep -w "/O/0/d$((objid%32))" -C 5 |
24479                           awk '/Object/{getline; print $1}')
24480         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24481                           awk "/$objid = /"'{printf $3}')
24482
24483         echo $zfs_objid
24484 }
24485
24486 zfs_object_blksz() {
24487         local ost=$1
24488         local objid=$2
24489
24490         local vdevdir=$(dirname $(facet_vdevice $ost))
24491         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24492         local blksz=$(do_facet $ost $cmd $objid |
24493                       awk '/dblk/{getline; printf $4}')
24494
24495         case "${blksz: -1}" in
24496                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24497                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24498                 *) ;;
24499         esac
24500
24501         echo $blksz
24502 }
24503
24504 test_312() { # LU-4856
24505         remote_ost_nodsh && skip "remote OST with nodsh"
24506         [ "$ost1_FSTYPE" = "zfs" ] ||
24507                 skip_env "the test only applies to zfs"
24508
24509         local max_blksz=$(do_facet ost1 \
24510                           $ZFS get -p recordsize $(facet_device ost1) |
24511                           awk '!/VALUE/{print $3}')
24512
24513         # to make life a little bit easier
24514         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24515         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24516
24517         local tf=$DIR/$tdir/$tfile
24518         touch $tf
24519         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24520
24521         # Get ZFS object id
24522         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24523         # block size change by sequential overwrite
24524         local bs
24525
24526         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24527                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24528
24529                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24530                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24531         done
24532         rm -f $tf
24533
24534         # block size change by sequential append write
24535         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24536         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24537         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24538         local count
24539
24540         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24541                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24542                         oflag=sync conv=notrunc
24543
24544                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24545                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24546                         error "blksz error, actual $blksz, " \
24547                                 "expected: 2 * $count * $PAGE_SIZE"
24548         done
24549         rm -f $tf
24550
24551         # random write
24552         touch $tf
24553         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24554         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24555
24556         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24557         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24558         [ $blksz -eq $PAGE_SIZE ] ||
24559                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24560
24561         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24562         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24563         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24564
24565         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24566         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24567         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24568 }
24569 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24570
24571 test_313() {
24572         remote_ost_nodsh && skip "remote OST with nodsh"
24573
24574         local file=$DIR/$tfile
24575
24576         rm -f $file
24577         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24578
24579         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24580         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24581         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24582                 error "write should failed"
24583         do_facet ost1 "$LCTL set_param fail_loc=0"
24584         rm -f $file
24585 }
24586 run_test 313 "io should fail after last_rcvd update fail"
24587
24588 test_314() {
24589         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24590
24591         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24592         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24593         rm -f $DIR/$tfile
24594         wait_delete_completed
24595         do_facet ost1 "$LCTL set_param fail_loc=0"
24596 }
24597 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24598
24599 test_315() { # LU-618
24600         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24601
24602         local file=$DIR/$tfile
24603         rm -f $file
24604
24605         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24606                 error "multiop file write failed"
24607         $MULTIOP $file oO_RDONLY:r4063232_c &
24608         PID=$!
24609
24610         sleep 2
24611
24612         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24613         kill -USR1 $PID
24614
24615         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24616         rm -f $file
24617 }
24618 run_test 315 "read should be accounted"
24619
24620 test_316() {
24621         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24622         large_xattr_enabled || skip "ea_inode feature disabled"
24623
24624         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24625         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24626         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24627         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24628
24629         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24630 }
24631 run_test 316 "lfs migrate of file with large_xattr enabled"
24632
24633 test_317() {
24634         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24635                 skip "Need MDS version at least 2.11.53"
24636         if [ "$ost1_FSTYPE" == "zfs" ]; then
24637                 skip "LU-10370: no implementation for ZFS"
24638         fi
24639
24640         local trunc_sz
24641         local grant_blk_size
24642
24643         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24644                         awk '/grant_block_size:/ { print $2; exit; }')
24645         #
24646         # Create File of size 5M. Truncate it to below size's and verify
24647         # blocks count.
24648         #
24649         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24650                 error "Create file $DIR/$tfile failed"
24651         stack_trap "rm -f $DIR/$tfile" EXIT
24652
24653         for trunc_sz in 2097152 4097 4000 509 0; do
24654                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24655                         error "truncate $tfile to $trunc_sz failed"
24656                 local sz=$(stat --format=%s $DIR/$tfile)
24657                 local blk=$(stat --format=%b $DIR/$tfile)
24658                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24659                                      grant_blk_size) * 8))
24660
24661                 if [[ $blk -ne $trunc_blk ]]; then
24662                         $(which stat) $DIR/$tfile
24663                         error "Expected Block $trunc_blk got $blk for $tfile"
24664                 fi
24665
24666                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24667                         error "Expected Size $trunc_sz got $sz for $tfile"
24668         done
24669
24670         #
24671         # sparse file test
24672         # Create file with a hole and write actual 65536 bytes which aligned
24673         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24674         #
24675         local bs=65536
24676         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24677                 error "Create file : $DIR/$tfile"
24678
24679         #
24680         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24681         # blocks. The block count must drop to 8.
24682         #
24683         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24684                 ((bs - grant_blk_size) + 1)))
24685         $TRUNCATE $DIR/$tfile $trunc_sz ||
24686                 error "truncate $tfile to $trunc_sz failed"
24687
24688         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24689         sz=$(stat --format=%s $DIR/$tfile)
24690         blk=$(stat --format=%b $DIR/$tfile)
24691
24692         if [[ $blk -ne $trunc_bsz ]]; then
24693                 $(which stat) $DIR/$tfile
24694                 error "Expected Block $trunc_bsz got $blk for $tfile"
24695         fi
24696
24697         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24698                 error "Expected Size $trunc_sz got $sz for $tfile"
24699 }
24700 run_test 317 "Verify blocks get correctly update after truncate"
24701
24702 test_318() {
24703         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24704         local old_max_active=$($LCTL get_param -n \
24705                             ${llite_name}.max_read_ahead_async_active \
24706                             2>/dev/null)
24707
24708         $LCTL set_param llite.*.max_read_ahead_async_active=256
24709         local max_active=$($LCTL get_param -n \
24710                            ${llite_name}.max_read_ahead_async_active \
24711                            2>/dev/null)
24712         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24713
24714         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24715                 error "set max_read_ahead_async_active should succeed"
24716
24717         $LCTL set_param llite.*.max_read_ahead_async_active=512
24718         max_active=$($LCTL get_param -n \
24719                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24720         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24721
24722         # restore @max_active
24723         [ $old_max_active -ne 0 ] && $LCTL set_param \
24724                 llite.*.max_read_ahead_async_active=$old_max_active
24725
24726         local old_threshold=$($LCTL get_param -n \
24727                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24728         local max_per_file_mb=$($LCTL get_param -n \
24729                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24730
24731         local invalid=$(($max_per_file_mb + 1))
24732         $LCTL set_param \
24733                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24734                         && error "set $invalid should fail"
24735
24736         local valid=$(($invalid - 1))
24737         $LCTL set_param \
24738                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24739                         error "set $valid should succeed"
24740         local threshold=$($LCTL get_param -n \
24741                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24742         [ $threshold -eq $valid ] || error \
24743                 "expect threshold $valid got $threshold"
24744         $LCTL set_param \
24745                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24746 }
24747 run_test 318 "Verify async readahead tunables"
24748
24749 test_319() {
24750         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24751
24752         local before=$(date +%s)
24753         local evict
24754         local mdir=$DIR/$tdir
24755         local file=$mdir/xxx
24756
24757         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24758         touch $file
24759
24760 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24761         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24762         $LFS migrate -m1 $mdir &
24763
24764         sleep 1
24765         dd if=$file of=/dev/null
24766         wait
24767         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24768           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24769
24770         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24771 }
24772 run_test 319 "lost lease lock on migrate error"
24773
24774 test_398a() { # LU-4198
24775         local ost1_imp=$(get_osc_import_name client ost1)
24776         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24777                          cut -d'.' -f2)
24778
24779         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24780         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24781
24782         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24783         # request a new lock on client
24784         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24785
24786         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24787         #local lock_count=$($LCTL get_param -n \
24788         #                  ldlm.namespaces.$imp_name.lru_size)
24789         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24790
24791         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24792
24793         # no lock cached, should use lockless DIO and not enqueue new lock
24794         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24795                 conv=notrunc ||
24796                 error "dio write failed"
24797         lock_count=$($LCTL get_param -n \
24798                      ldlm.namespaces.$imp_name.lru_size)
24799         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24800
24801         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24802
24803         # no lock cached, should use locked DIO append
24804         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24805                 conv=notrunc || error "DIO append failed"
24806         lock_count=$($LCTL get_param -n \
24807                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24808         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24809 }
24810 run_test 398a "direct IO should cancel lock otherwise lockless"
24811
24812 test_398b() { # LU-4198
24813         which fio || skip_env "no fio installed"
24814         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24815
24816         local size=48
24817         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24818
24819         local njobs=4
24820         # Single page, multiple pages, stripe size, 4*stripe size
24821         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24822                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24823                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24824                         --numjobs=$njobs --fallocate=none \
24825                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24826                         --filename=$DIR/$tfile &
24827                 bg_pid=$!
24828
24829                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24830                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24831                         --numjobs=$njobs --fallocate=none \
24832                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24833                         --filename=$DIR/$tfile || true
24834                 wait $bg_pid
24835         done
24836
24837         evict=$(do_facet client $LCTL get_param \
24838                 osc.$FSNAME-OST*-osc-*/state |
24839             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24840
24841         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24842                 (do_facet client $LCTL get_param \
24843                         osc.$FSNAME-OST*-osc-*/state;
24844                     error "eviction happened: $evict before:$before")
24845
24846         rm -f $DIR/$tfile
24847 }
24848 run_test 398b "DIO and buffer IO race"
24849
24850 test_398c() { # LU-4198
24851         local ost1_imp=$(get_osc_import_name client ost1)
24852         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24853                          cut -d'.' -f2)
24854
24855         which fio || skip_env "no fio installed"
24856
24857         saved_debug=$($LCTL get_param -n debug)
24858         $LCTL set_param debug=0
24859
24860         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24861         ((size /= 1024)) # by megabytes
24862         ((size /= 2)) # write half of the OST at most
24863         [ $size -gt 40 ] && size=40 #reduce test time anyway
24864
24865         $LFS setstripe -c 1 $DIR/$tfile
24866
24867         # it seems like ldiskfs reserves more space than necessary if the
24868         # writing blocks are not mapped, so it extends the file firstly
24869         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24870         cancel_lru_locks osc
24871
24872         # clear and verify rpc_stats later
24873         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24874
24875         local njobs=4
24876         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24877         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24878                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24879                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24880                 --filename=$DIR/$tfile
24881         [ $? -eq 0 ] || error "fio write error"
24882
24883         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24884                 error "Locks were requested while doing AIO"
24885
24886         # get the percentage of 1-page I/O
24887         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24888                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24889                 awk '{print $7}')
24890         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24891
24892         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24893         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24894                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24895                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24896                 --filename=$DIR/$tfile
24897         [ $? -eq 0 ] || error "fio mixed read write error"
24898
24899         echo "AIO with large block size ${size}M"
24900         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24901                 --numjobs=1 --fallocate=none --ioengine=libaio \
24902                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24903                 --filename=$DIR/$tfile
24904         [ $? -eq 0 ] || error "fio large block size failed"
24905
24906         rm -f $DIR/$tfile
24907         $LCTL set_param debug="$saved_debug"
24908 }
24909 run_test 398c "run fio to test AIO"
24910
24911 test_398d() { #  LU-13846
24912         which aiocp || skip_env "no aiocp installed"
24913         local aio_file=$DIR/$tfile.aio
24914
24915         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24916
24917         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24918         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24919         stack_trap "rm -f $DIR/$tfile $aio_file"
24920
24921         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24922
24923         # make sure we don't crash and fail properly
24924         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24925                 error "aio not aligned with PAGE SIZE should fail"
24926
24927         rm -f $DIR/$tfile $aio_file
24928 }
24929 run_test 398d "run aiocp to verify block size > stripe size"
24930
24931 test_398e() {
24932         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24933         touch $DIR/$tfile.new
24934         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24935 }
24936 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24937
24938 test_398f() { #  LU-14687
24939         which aiocp || skip_env "no aiocp installed"
24940         local aio_file=$DIR/$tfile.aio
24941
24942         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24943
24944         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24945         stack_trap "rm -f $DIR/$tfile $aio_file"
24946
24947         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24948         $LCTL set_param fail_loc=0x1418
24949         # make sure we don't crash and fail properly
24950         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24951                 error "aio with page allocation failure succeeded"
24952         $LCTL set_param fail_loc=0
24953         diff $DIR/$tfile $aio_file
24954         [[ $? != 0 ]] || error "no diff after failed aiocp"
24955 }
24956 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24957
24958 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24959 # stripe and i/o size must be > stripe size
24960 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24961 # single RPC in flight.  This test shows async DIO submission is working by
24962 # showing multiple RPCs in flight.
24963 test_398g() { #  LU-13798
24964         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24965
24966         # We need to do some i/o first to acquire enough grant to put our RPCs
24967         # in flight; otherwise a new connection may not have enough grant
24968         # available
24969         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24970                 error "parallel dio failed"
24971         stack_trap "rm -f $DIR/$tfile"
24972
24973         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24974         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24975         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24976         stack_trap "$LCTL set_param -n $pages_per_rpc"
24977
24978         # Recreate file so it's empty
24979         rm -f $DIR/$tfile
24980         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24981         #Pause rpc completion to guarantee we see multiple rpcs in flight
24982         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24983         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24984         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24985
24986         # Clear rpc stats
24987         $LCTL set_param osc.*.rpc_stats=c
24988
24989         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24990                 error "parallel dio failed"
24991         stack_trap "rm -f $DIR/$tfile"
24992
24993         $LCTL get_param osc.*-OST0000-*.rpc_stats
24994         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24995                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24996                 grep "8:" | awk '{print $8}')
24997         # We look at the "8 rpcs in flight" field, and verify A) it is present
24998         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24999         # as expected for an 8M DIO to a file with 1M stripes.
25000         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25001
25002         # Verify turning off parallel dio works as expected
25003         # Clear rpc stats
25004         $LCTL set_param osc.*.rpc_stats=c
25005         $LCTL set_param llite.*.parallel_dio=0
25006         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25007
25008         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25009                 error "dio with parallel dio disabled failed"
25010
25011         # Ideally, we would see only one RPC in flight here, but there is an
25012         # unavoidable race between i/o completion and RPC in flight counting,
25013         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25014         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25015         # So instead we just verify it's always < 8.
25016         $LCTL get_param osc.*-OST0000-*.rpc_stats
25017         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25018                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25019                 grep '^$' -B1 | grep . | awk '{print $1}')
25020         [ $ret != "8:" ] ||
25021                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25022 }
25023 run_test 398g "verify parallel dio async RPC submission"
25024
25025 test_398h() { #  LU-13798
25026         local dio_file=$DIR/$tfile.dio
25027
25028         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25029
25030         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25031         stack_trap "rm -f $DIR/$tfile $dio_file"
25032
25033         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25034                 error "parallel dio failed"
25035         diff $DIR/$tfile $dio_file
25036         [[ $? == 0 ]] || error "file diff after aiocp"
25037 }
25038 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25039
25040 test_398i() { #  LU-13798
25041         local dio_file=$DIR/$tfile.dio
25042
25043         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25044
25045         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25046         stack_trap "rm -f $DIR/$tfile $dio_file"
25047
25048         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25049         $LCTL set_param fail_loc=0x1418
25050         # make sure we don't crash and fail properly
25051         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25052                 error "parallel dio page allocation failure succeeded"
25053         diff $DIR/$tfile $dio_file
25054         [[ $? != 0 ]] || error "no diff after failed aiocp"
25055 }
25056 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25057
25058 test_398j() { #  LU-13798
25059         # Stripe size > RPC size but less than i/o size tests split across
25060         # stripes and RPCs for individual i/o op
25061         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25062
25063         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25064         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25065         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25066         stack_trap "$LCTL set_param -n $pages_per_rpc"
25067
25068         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25069                 error "parallel dio write failed"
25070         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25071
25072         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25073                 error "parallel dio read failed"
25074         diff $DIR/$tfile $DIR/$tfile.2
25075         [[ $? == 0 ]] || error "file diff after parallel dio read"
25076 }
25077 run_test 398j "test parallel dio where stripe size > rpc_size"
25078
25079 test_398k() { #  LU-13798
25080         wait_delete_completed
25081         wait_mds_ost_sync
25082
25083         # 4 stripe file; we will cause out of space on OST0
25084         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25085
25086         # Fill OST0 (if it's not too large)
25087         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25088                    head -n1)
25089         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25090                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25091         fi
25092         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25093         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25094                 error "dd should fill OST0"
25095         stack_trap "rm -f $DIR/$tfile.1"
25096
25097         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25098         err=$?
25099
25100         ls -la $DIR/$tfile
25101         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25102                 error "file is not 0 bytes in size"
25103
25104         # dd above should not succeed, but don't error until here so we can
25105         # get debug info above
25106         [[ $err != 0 ]] ||
25107                 error "parallel dio write with enospc succeeded"
25108         stack_trap "rm -f $DIR/$tfile"
25109 }
25110 run_test 398k "test enospc on first stripe"
25111
25112 test_398l() { #  LU-13798
25113         wait_delete_completed
25114         wait_mds_ost_sync
25115
25116         # 4 stripe file; we will cause out of space on OST0
25117         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25118         # happens on the second i/o chunk we issue
25119         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25120
25121         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25122         stack_trap "rm -f $DIR/$tfile"
25123
25124         # Fill OST0 (if it's not too large)
25125         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25126                    head -n1)
25127         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25128                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25129         fi
25130         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25131         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25132                 error "dd should fill OST0"
25133         stack_trap "rm -f $DIR/$tfile.1"
25134
25135         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25136         err=$?
25137         stack_trap "rm -f $DIR/$tfile.2"
25138
25139         # Check that short write completed as expected
25140         ls -la $DIR/$tfile.2
25141         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25142                 error "file is not 1M in size"
25143
25144         # dd above should not succeed, but don't error until here so we can
25145         # get debug info above
25146         [[ $err != 0 ]] ||
25147                 error "parallel dio write with enospc succeeded"
25148
25149         # Truncate source file to same length as output file and diff them
25150         $TRUNCATE $DIR/$tfile 1048576
25151         diff $DIR/$tfile $DIR/$tfile.2
25152         [[ $? == 0 ]] || error "data incorrect after short write"
25153 }
25154 run_test 398l "test enospc on intermediate stripe/RPC"
25155
25156 test_398m() { #  LU-13798
25157         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25158
25159         # Set up failure on OST0, the first stripe:
25160         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25161         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25162         # So this fail_val specifies OST0
25163         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25164         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25165
25166         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25167                 error "parallel dio write with failure on first stripe succeeded"
25168         stack_trap "rm -f $DIR/$tfile"
25169         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25170
25171         # Place data in file for read
25172         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25173                 error "parallel dio write failed"
25174
25175         # Fail read on OST0, first stripe
25176         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25177         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25178         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25179                 error "parallel dio read with error on first stripe succeeded"
25180         rm -f $DIR/$tfile.2
25181         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25182
25183         # Switch to testing on OST1, second stripe
25184         # Clear file contents, maintain striping
25185         echo > $DIR/$tfile
25186         # Set up failure on OST1, second stripe:
25187         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25188         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25189
25190         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25191                 error "parallel dio write with failure on first stripe succeeded"
25192         stack_trap "rm -f $DIR/$tfile"
25193         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25194
25195         # Place data in file for read
25196         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25197                 error "parallel dio write failed"
25198
25199         # Fail read on OST1, second stripe
25200         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25201         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25202         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25203                 error "parallel dio read with error on first stripe succeeded"
25204         rm -f $DIR/$tfile.2
25205         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25206 }
25207 run_test 398m "test RPC failures with parallel dio"
25208
25209 # Parallel submission of DIO should not cause problems for append, but it's
25210 # important to verify.
25211 test_398n() { #  LU-13798
25212         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25213
25214         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25215                 error "dd to create source file failed"
25216         stack_trap "rm -f $DIR/$tfile"
25217
25218         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25219                 error "parallel dio write with failure on second stripe succeeded"
25220         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25221         diff $DIR/$tfile $DIR/$tfile.1
25222         [[ $? == 0 ]] || error "data incorrect after append"
25223
25224 }
25225 run_test 398n "test append with parallel DIO"
25226
25227 test_398o() {
25228         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25229 }
25230 run_test 398o "right kms with DIO"
25231
25232 test_fake_rw() {
25233         local read_write=$1
25234         if [ "$read_write" = "write" ]; then
25235                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25236         elif [ "$read_write" = "read" ]; then
25237                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25238         else
25239                 error "argument error"
25240         fi
25241
25242         # turn off debug for performance testing
25243         local saved_debug=$($LCTL get_param -n debug)
25244         $LCTL set_param debug=0
25245
25246         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25247
25248         # get ost1 size - $FSNAME-OST0000
25249         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25250         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25251         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25252
25253         if [ "$read_write" = "read" ]; then
25254                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25255         fi
25256
25257         local start_time=$(date +%s.%N)
25258         $dd_cmd bs=1M count=$blocks oflag=sync ||
25259                 error "real dd $read_write error"
25260         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25261
25262         if [ "$read_write" = "write" ]; then
25263                 rm -f $DIR/$tfile
25264         fi
25265
25266         # define OBD_FAIL_OST_FAKE_RW           0x238
25267         do_facet ost1 $LCTL set_param fail_loc=0x238
25268
25269         local start_time=$(date +%s.%N)
25270         $dd_cmd bs=1M count=$blocks oflag=sync ||
25271                 error "fake dd $read_write error"
25272         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25273
25274         if [ "$read_write" = "write" ]; then
25275                 # verify file size
25276                 cancel_lru_locks osc
25277                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25278                         error "$tfile size not $blocks MB"
25279         fi
25280         do_facet ost1 $LCTL set_param fail_loc=0
25281
25282         echo "fake $read_write $duration_fake vs. normal $read_write" \
25283                 "$duration in seconds"
25284         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25285                 error_not_in_vm "fake write is slower"
25286
25287         $LCTL set_param -n debug="$saved_debug"
25288         rm -f $DIR/$tfile
25289 }
25290 test_399a() { # LU-7655 for OST fake write
25291         remote_ost_nodsh && skip "remote OST with nodsh"
25292
25293         test_fake_rw write
25294 }
25295 run_test 399a "fake write should not be slower than normal write"
25296
25297 test_399b() { # LU-8726 for OST fake read
25298         remote_ost_nodsh && skip "remote OST with nodsh"
25299         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25300                 skip_env "ldiskfs only test"
25301         fi
25302
25303         test_fake_rw read
25304 }
25305 run_test 399b "fake read should not be slower than normal read"
25306
25307 test_400a() { # LU-1606, was conf-sanity test_74
25308         if ! which $CC > /dev/null 2>&1; then
25309                 skip_env "$CC is not installed"
25310         fi
25311
25312         local extra_flags=''
25313         local out=$TMP/$tfile
25314         local prefix=/usr/include/lustre
25315         local prog
25316
25317         # Oleg removes c files in his test rig so test if any c files exist
25318         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25319                 skip_env "Needed c test files are missing"
25320
25321         if ! [[ -d $prefix ]]; then
25322                 # Assume we're running in tree and fixup the include path.
25323                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25324                 extra_flags+=" -L$LUSTRE/utils/.lib"
25325         fi
25326
25327         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25328                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25329                         error "client api broken"
25330         done
25331         rm -f $out
25332 }
25333 run_test 400a "Lustre client api program can compile and link"
25334
25335 test_400b() { # LU-1606, LU-5011
25336         local header
25337         local out=$TMP/$tfile
25338         local prefix=/usr/include/linux/lustre
25339
25340         # We use a hard coded prefix so that this test will not fail
25341         # when run in tree. There are headers in lustre/include/lustre/
25342         # that are not packaged (like lustre_idl.h) and have more
25343         # complicated include dependencies (like config.h and lnet/types.h).
25344         # Since this test about correct packaging we just skip them when
25345         # they don't exist (see below) rather than try to fixup cppflags.
25346
25347         if ! which $CC > /dev/null 2>&1; then
25348                 skip_env "$CC is not installed"
25349         fi
25350
25351         for header in $prefix/*.h; do
25352                 if ! [[ -f "$header" ]]; then
25353                         continue
25354                 fi
25355
25356                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25357                         continue # lustre_ioctl.h is internal header
25358                 fi
25359
25360                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25361                         error "cannot compile '$header'"
25362         done
25363         rm -f $out
25364 }
25365 run_test 400b "packaged headers can be compiled"
25366
25367 test_401a() { #LU-7437
25368         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25369         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25370
25371         #count the number of parameters by "list_param -R"
25372         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25373         #count the number of parameters by listing proc files
25374         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25375         echo "proc_dirs='$proc_dirs'"
25376         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25377         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25378                       sort -u | wc -l)
25379
25380         [ $params -eq $procs ] ||
25381                 error "found $params parameters vs. $procs proc files"
25382
25383         # test the list_param -D option only returns directories
25384         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25385         #count the number of parameters by listing proc directories
25386         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25387                 sort -u | wc -l)
25388
25389         [ $params -eq $procs ] ||
25390                 error "found $params parameters vs. $procs proc files"
25391 }
25392 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25393
25394 test_401b() {
25395         # jobid_var may not allow arbitrary values, so use jobid_name
25396         # if available
25397         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25398                 local testname=jobid_name tmp='testing%p'
25399         else
25400                 local testname=jobid_var tmp=testing
25401         fi
25402
25403         local save=$($LCTL get_param -n $testname)
25404
25405         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25406                 error "no error returned when setting bad parameters"
25407
25408         local jobid_new=$($LCTL get_param -n foe $testname baz)
25409         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25410
25411         $LCTL set_param -n fog=bam $testname=$save bat=fog
25412         local jobid_old=$($LCTL get_param -n foe $testname bag)
25413         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25414 }
25415 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25416
25417 test_401c() {
25418         # jobid_var may not allow arbitrary values, so use jobid_name
25419         # if available
25420         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25421                 local testname=jobid_name
25422         else
25423                 local testname=jobid_var
25424         fi
25425
25426         local jobid_var_old=$($LCTL get_param -n $testname)
25427         local jobid_var_new
25428
25429         $LCTL set_param $testname= &&
25430                 error "no error returned for 'set_param a='"
25431
25432         jobid_var_new=$($LCTL get_param -n $testname)
25433         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25434                 error "$testname was changed by setting without value"
25435
25436         $LCTL set_param $testname &&
25437                 error "no error returned for 'set_param a'"
25438
25439         jobid_var_new=$($LCTL get_param -n $testname)
25440         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25441                 error "$testname was changed by setting without value"
25442 }
25443 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25444
25445 test_401d() {
25446         # jobid_var may not allow arbitrary values, so use jobid_name
25447         # if available
25448         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25449                 local testname=jobid_name new_value='foo=bar%p'
25450         else
25451                 local testname=jobid_var new_valuie=foo=bar
25452         fi
25453
25454         local jobid_var_old=$($LCTL get_param -n $testname)
25455         local jobid_var_new
25456
25457         $LCTL set_param $testname=$new_value ||
25458                 error "'set_param a=b' did not accept a value containing '='"
25459
25460         jobid_var_new=$($LCTL get_param -n $testname)
25461         [[ "$jobid_var_new" == "$new_value" ]] ||
25462                 error "'set_param a=b' failed on a value containing '='"
25463
25464         # Reset the $testname to test the other format
25465         $LCTL set_param $testname=$jobid_var_old
25466         jobid_var_new=$($LCTL get_param -n $testname)
25467         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25468                 error "failed to reset $testname"
25469
25470         $LCTL set_param $testname $new_value ||
25471                 error "'set_param a b' did not accept a value containing '='"
25472
25473         jobid_var_new=$($LCTL get_param -n $testname)
25474         [[ "$jobid_var_new" == "$new_value" ]] ||
25475                 error "'set_param a b' failed on a value containing '='"
25476
25477         $LCTL set_param $testname $jobid_var_old
25478         jobid_var_new=$($LCTL get_param -n $testname)
25479         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25480                 error "failed to reset $testname"
25481 }
25482 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25483
25484 test_401e() { # LU-14779
25485         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25486                 error "lctl list_param MGC* failed"
25487         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25488         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25489                 error "lctl get_param lru_size failed"
25490 }
25491 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25492
25493 test_402() {
25494         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25495         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25496                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25497         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25498                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25499                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25500         remote_mds_nodsh && skip "remote MDS with nodsh"
25501
25502         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25503 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25504         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25505         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25506                 echo "Touch failed - OK"
25507 }
25508 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25509
25510 test_403() {
25511         local file1=$DIR/$tfile.1
25512         local file2=$DIR/$tfile.2
25513         local tfile=$TMP/$tfile
25514
25515         rm -f $file1 $file2 $tfile
25516
25517         touch $file1
25518         ln $file1 $file2
25519
25520         # 30 sec OBD_TIMEOUT in ll_getattr()
25521         # right before populating st_nlink
25522         $LCTL set_param fail_loc=0x80001409
25523         stat -c %h $file1 > $tfile &
25524
25525         # create an alias, drop all locks and reclaim the dentry
25526         < $file2
25527         cancel_lru_locks mdc
25528         cancel_lru_locks osc
25529         sysctl -w vm.drop_caches=2
25530
25531         wait
25532
25533         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25534
25535         rm -f $tfile $file1 $file2
25536 }
25537 run_test 403 "i_nlink should not drop to zero due to aliasing"
25538
25539 test_404() { # LU-6601
25540         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25541                 skip "Need server version newer than 2.8.52"
25542         remote_mds_nodsh && skip "remote MDS with nodsh"
25543
25544         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25545                 awk '/osp .*-osc-MDT/ { print $4}')
25546
25547         local osp
25548         for osp in $mosps; do
25549                 echo "Deactivate: " $osp
25550                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25551                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25552                         awk -vp=$osp '$4 == p { print $2 }')
25553                 [ $stat = IN ] || {
25554                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25555                         error "deactivate error"
25556                 }
25557                 echo "Activate: " $osp
25558                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25559                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25560                         awk -vp=$osp '$4 == p { print $2 }')
25561                 [ $stat = UP ] || {
25562                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25563                         error "activate error"
25564                 }
25565         done
25566 }
25567 run_test 404 "validate manual {de}activated works properly for OSPs"
25568
25569 test_405() {
25570         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25571         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25572                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25573                         skip "Layout swap lock is not supported"
25574
25575         check_swap_layouts_support
25576         check_swap_layout_no_dom $DIR
25577
25578         test_mkdir $DIR/$tdir
25579         swap_lock_test -d $DIR/$tdir ||
25580                 error "One layout swap locked test failed"
25581 }
25582 run_test 405 "Various layout swap lock tests"
25583
25584 test_406() {
25585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25586         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25587         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25589         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25590                 skip "Need MDS version at least 2.8.50"
25591
25592         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25593         local test_pool=$TESTNAME
25594
25595         pool_add $test_pool || error "pool_add failed"
25596         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25597                 error "pool_add_targets failed"
25598
25599         save_layout_restore_at_exit $MOUNT
25600
25601         # parent set default stripe count only, child will stripe from both
25602         # parent and fs default
25603         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25604                 error "setstripe $MOUNT failed"
25605         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25606         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25607         for i in $(seq 10); do
25608                 local f=$DIR/$tdir/$tfile.$i
25609                 touch $f || error "touch failed"
25610                 local count=$($LFS getstripe -c $f)
25611                 [ $count -eq $OSTCOUNT ] ||
25612                         error "$f stripe count $count != $OSTCOUNT"
25613                 local offset=$($LFS getstripe -i $f)
25614                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25615                 local size=$($LFS getstripe -S $f)
25616                 [ $size -eq $((def_stripe_size * 2)) ] ||
25617                         error "$f stripe size $size != $((def_stripe_size * 2))"
25618                 local pool=$($LFS getstripe -p $f)
25619                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25620         done
25621
25622         # change fs default striping, delete parent default striping, now child
25623         # will stripe from new fs default striping only
25624         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25625                 error "change $MOUNT default stripe failed"
25626         $LFS setstripe -c 0 $DIR/$tdir ||
25627                 error "delete $tdir default stripe failed"
25628         for i in $(seq 11 20); do
25629                 local f=$DIR/$tdir/$tfile.$i
25630                 touch $f || error "touch $f failed"
25631                 local count=$($LFS getstripe -c $f)
25632                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25633                 local offset=$($LFS getstripe -i $f)
25634                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25635                 local size=$($LFS getstripe -S $f)
25636                 [ $size -eq $def_stripe_size ] ||
25637                         error "$f stripe size $size != $def_stripe_size"
25638                 local pool=$($LFS getstripe -p $f)
25639                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25640         done
25641
25642         unlinkmany $DIR/$tdir/$tfile. 1 20
25643
25644         local f=$DIR/$tdir/$tfile
25645         pool_remove_all_targets $test_pool $f
25646         pool_remove $test_pool $f
25647 }
25648 run_test 406 "DNE support fs default striping"
25649
25650 test_407() {
25651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25652         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25653                 skip "Need MDS version at least 2.8.55"
25654         remote_mds_nodsh && skip "remote MDS with nodsh"
25655
25656         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25657                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25658         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25659                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25660         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25661
25662         #define OBD_FAIL_DT_TXN_STOP    0x2019
25663         for idx in $(seq $MDSCOUNT); do
25664                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25665         done
25666         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25667         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25668                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25669         true
25670 }
25671 run_test 407 "transaction fail should cause operation fail"
25672
25673 test_408() {
25674         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25675
25676         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25677         lctl set_param fail_loc=0x8000040a
25678         # let ll_prepare_partial_page() fail
25679         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25680
25681         rm -f $DIR/$tfile
25682
25683         # create at least 100 unused inodes so that
25684         # shrink_icache_memory(0) should not return 0
25685         touch $DIR/$tfile-{0..100}
25686         rm -f $DIR/$tfile-{0..100}
25687         sync
25688
25689         echo 2 > /proc/sys/vm/drop_caches
25690 }
25691 run_test 408 "drop_caches should not hang due to page leaks"
25692
25693 test_409()
25694 {
25695         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25696
25697         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25698         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25699         touch $DIR/$tdir/guard || error "(2) Fail to create"
25700
25701         local PREFIX=$(str_repeat 'A' 128)
25702         echo "Create 1K hard links start at $(date)"
25703         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25704                 error "(3) Fail to hard link"
25705
25706         echo "Links count should be right although linkEA overflow"
25707         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25708         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25709         [ $linkcount -eq 1001 ] ||
25710                 error "(5) Unexpected hard links count: $linkcount"
25711
25712         echo "List all links start at $(date)"
25713         ls -l $DIR/$tdir/foo > /dev/null ||
25714                 error "(6) Fail to list $DIR/$tdir/foo"
25715
25716         echo "Unlink hard links start at $(date)"
25717         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25718                 error "(7) Fail to unlink"
25719         echo "Unlink hard links finished at $(date)"
25720 }
25721 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25722
25723 test_410()
25724 {
25725         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25726                 skip "Need client version at least 2.9.59"
25727         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25728                 skip "Need MODULES build"
25729
25730         # Create a file, and stat it from the kernel
25731         local testfile=$DIR/$tfile
25732         touch $testfile
25733
25734         local run_id=$RANDOM
25735         local my_ino=$(stat --format "%i" $testfile)
25736
25737         # Try to insert the module. This will always fail as the
25738         # module is designed to not be inserted.
25739         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25740             &> /dev/null
25741
25742         # Anything but success is a test failure
25743         dmesg | grep -q \
25744             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25745             error "no inode match"
25746 }
25747 run_test 410 "Test inode number returned from kernel thread"
25748
25749 cleanup_test411_cgroup() {
25750         trap 0
25751         rmdir "$1"
25752 }
25753
25754 test_411() {
25755         local cg_basedir=/sys/fs/cgroup/memory
25756         # LU-9966
25757         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25758                 skip "no setup for cgroup"
25759
25760         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25761                 error "test file creation failed"
25762         cancel_lru_locks osc
25763
25764         # Create a very small memory cgroup to force a slab allocation error
25765         local cgdir=$cg_basedir/osc_slab_alloc
25766         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25767         trap "cleanup_test411_cgroup $cgdir" EXIT
25768         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25769         echo 1M > $cgdir/memory.limit_in_bytes
25770
25771         # Should not LBUG, just be killed by oom-killer
25772         # dd will return 0 even allocation failure in some environment.
25773         # So don't check return value
25774         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25775         cleanup_test411_cgroup $cgdir
25776
25777         return 0
25778 }
25779 run_test 411 "Slab allocation error with cgroup does not LBUG"
25780
25781 test_412() {
25782         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25783         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25784                 skip "Need server version at least 2.10.55"
25785
25786         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25787                 error "mkdir failed"
25788         $LFS getdirstripe $DIR/$tdir
25789         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25790         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25791                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25792         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25793         [ $stripe_count -eq 2 ] ||
25794                 error "expect 2 get $stripe_count"
25795
25796         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25797
25798         local index
25799         local index2
25800
25801         # subdirs should be on the same MDT as parent
25802         for i in $(seq 0 $((MDSCOUNT - 1))); do
25803                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25804                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25805                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25806                 (( index == i )) || error "mdt$i/sub on MDT$index"
25807         done
25808
25809         # stripe offset -1, ditto
25810         for i in {1..10}; do
25811                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25812                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25813                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25814                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25815                 (( index == index2 )) ||
25816                         error "qos$i on MDT$index, sub on MDT$index2"
25817         done
25818
25819         local testdir=$DIR/$tdir/inherit
25820
25821         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25822         # inherit 2 levels
25823         for i in 1 2; do
25824                 testdir=$testdir/s$i
25825                 mkdir $testdir || error "mkdir $testdir failed"
25826                 index=$($LFS getstripe -m $testdir)
25827                 (( index == 1 )) ||
25828                         error "$testdir on MDT$index"
25829         done
25830
25831         # not inherit any more
25832         testdir=$testdir/s3
25833         mkdir $testdir || error "mkdir $testdir failed"
25834         getfattr -d -m dmv $testdir | grep dmv &&
25835                 error "default LMV set on $testdir" || true
25836 }
25837 run_test 412 "mkdir on specific MDTs"
25838
25839 TEST413_COUNT=${TEST413_COUNT:-200}
25840 generate_uneven_mdts() {
25841         local threshold=$1
25842         local lmv_qos_maxage
25843         local lod_qos_maxage
25844         local ffree
25845         local bavail
25846         local max
25847         local min
25848         local max_index
25849         local min_index
25850         local tmp
25851         local i
25852
25853         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25854         $LCTL set_param lmv.*.qos_maxage=1
25855         stack_trap "$LCTL set_param \
25856                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25857         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25858                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25859         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25860                 lod.*.mdt_qos_maxage=1
25861         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25862                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25863
25864         echo
25865         echo "Check for uneven MDTs: "
25866
25867         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25868         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25869         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25870
25871         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25872         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25873         max_index=0
25874         min_index=0
25875         for ((i = 1; i < ${#ffree[@]}; i++)); do
25876                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25877                 if [ $tmp -gt $max ]; then
25878                         max=$tmp
25879                         max_index=$i
25880                 fi
25881                 if [ $tmp -lt $min ]; then
25882                         min=$tmp
25883                         min_index=$i
25884                 fi
25885         done
25886
25887         (( ${ffree[min_index]} > 0 )) ||
25888                 skip "no free files in MDT$min_index"
25889         (( ${ffree[min_index]} < 10000000 )) ||
25890                 skip "too many free files in MDT$min_index"
25891
25892         # Check if we need to generate uneven MDTs
25893         local diff=$(((max - min) * 100 / min))
25894         local testdir=$DIR/$tdir-fillmdt
25895         local start
25896
25897         i=0
25898         while (( diff < threshold )); do
25899                 mkdir -p $testdir
25900                 # generate uneven MDTs, create till $threshold% diff
25901                 echo -n "weight diff=$diff% must be > $threshold% ..."
25902                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25903                 testdir=$DIR/$tdir-fillmdt/$i
25904                 [ -d $testdir ] && continue
25905                 $LFS mkdir -i $min_index $testdir ||
25906                         error "mkdir $testdir failed"
25907                 $LFS setstripe -E 1M -L mdt $testdir ||
25908                         error "setstripe $testdir failed"
25909                 start=$SECONDS
25910                 for ((F=0; F < TEST413_COUNT; F++)); do
25911                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25912                                 /dev/null 2>&1 || error "dd $F failed"
25913                 done
25914                 sync; sleep 1; sync
25915
25916                 # wait for QOS to update
25917                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25918
25919                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25920                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25921                 max=$(((${ffree[max_index]} >> 8) *
25922                         (${bavail[max_index]} * bsize >> 16)))
25923                 min=$(((${ffree[min_index]} >> 8) *
25924                         (${bavail[min_index]} * bsize >> 16)))
25925                 diff=$(((max - min) * 100 / min))
25926                 i=$((i + 1))
25927         done
25928
25929         echo "MDT filesfree available: ${ffree[*]}"
25930         echo "MDT blocks available: ${bavail[*]}"
25931         echo "weight diff=$diff%"
25932 }
25933
25934 test_qos_mkdir() {
25935         local mkdir_cmd=$1
25936         local stripe_count=$2
25937         local mdts=$(comma_list $(mdts_nodes))
25938
25939         local testdir
25940         local lmv_qos_prio_free
25941         local lmv_qos_threshold_rr
25942         local lmv_qos_maxage
25943         local lod_qos_prio_free
25944         local lod_qos_threshold_rr
25945         local lod_qos_maxage
25946         local count
25947         local i
25948
25949         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25950         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25951         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25952                 head -n1)
25953         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25954         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25955         stack_trap "$LCTL set_param \
25956                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25957         stack_trap "$LCTL set_param \
25958                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25959         stack_trap "$LCTL set_param \
25960                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25961
25962         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25963                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25964         lod_qos_prio_free=${lod_qos_prio_free%%%}
25965         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25966                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25967         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25968         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25969                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25970         stack_trap "do_nodes $mdts $LCTL set_param \
25971                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25972         stack_trap "do_nodes $mdts $LCTL set_param \
25973                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25974         stack_trap "do_nodes $mdts $LCTL set_param \
25975                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25976
25977         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25978         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25979
25980         testdir=$DIR/$tdir-s$stripe_count/rr
25981
25982         local stripe_index=$($LFS getstripe -m $testdir)
25983         local test_mkdir_rr=true
25984
25985         getfattr -d -m dmv -e hex $testdir | grep dmv
25986         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25987                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25988                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25989                         test_mkdir_rr=false
25990         fi
25991
25992         echo
25993         $test_mkdir_rr &&
25994                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25995                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25996
25997         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25998         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25999                 eval $mkdir_cmd $testdir/subdir$i ||
26000                         error "$mkdir_cmd subdir$i failed"
26001         done
26002
26003         for (( i = 0; i < $MDSCOUNT; i++ )); do
26004                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26005                 echo "$count directories created on MDT$i"
26006                 if $test_mkdir_rr; then
26007                         (( $count == 100 )) ||
26008                                 error "subdirs are not evenly distributed"
26009                 elif (( $i == $stripe_index )); then
26010                         (( $count == 100 * MDSCOUNT )) ||
26011                                 error "$count subdirs created on MDT$i"
26012                 else
26013                         (( $count == 0 )) ||
26014                                 error "$count subdirs created on MDT$i"
26015                 fi
26016
26017                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26018                         count=$($LFS getdirstripe $testdir/* |
26019                                 grep -c -P "^\s+$i\t")
26020                         echo "$count stripes created on MDT$i"
26021                         # deviation should < 5% of average
26022                         (( $count >= 95 * stripe_count &&
26023                            $count <= 105 * stripe_count)) ||
26024                                 error "stripes are not evenly distributed"
26025                 fi
26026         done
26027
26028         echo
26029         echo "Check for uneven MDTs: "
26030
26031         local ffree
26032         local bavail
26033         local max
26034         local min
26035         local max_index
26036         local min_index
26037         local tmp
26038
26039         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26040         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26041         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26042
26043         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26044         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26045         max_index=0
26046         min_index=0
26047         for ((i = 1; i < ${#ffree[@]}; i++)); do
26048                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26049                 if [ $tmp -gt $max ]; then
26050                         max=$tmp
26051                         max_index=$i
26052                 fi
26053                 if [ $tmp -lt $min ]; then
26054                         min=$tmp
26055                         min_index=$i
26056                 fi
26057         done
26058
26059         (( ${ffree[min_index]} > 0 )) ||
26060                 skip "no free files in MDT$min_index"
26061         (( ${ffree[min_index]} < 10000000 )) ||
26062                 skip "too many free files in MDT$min_index"
26063
26064         echo "MDT filesfree available: ${ffree[*]}"
26065         echo "MDT blocks available: ${bavail[*]}"
26066         echo "weight diff=$(((max - min) * 100 / min))%"
26067         echo
26068         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26069
26070         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26071         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26072         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26073         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26074         # decrease statfs age, so that it can be updated in time
26075         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26076         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26077
26078         sleep 1
26079
26080         testdir=$DIR/$tdir-s$stripe_count/qos
26081         local num=200
26082
26083         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26084         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26085                 eval $mkdir_cmd $testdir/subdir$i ||
26086                         error "$mkdir_cmd subdir$i failed"
26087         done
26088
26089         max=0
26090         for (( i = 0; i < $MDSCOUNT; i++ )); do
26091                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26092                 (( count > max )) && max=$count
26093                 echo "$count directories created on MDT$i"
26094         done
26095
26096         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26097
26098         # D-value should > 10% of averge
26099         (( max - min > num / 10 )) ||
26100                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26101
26102         # ditto for stripes
26103         if (( stripe_count > 1 )); then
26104                 max=0
26105                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26106                         count=$($LFS getdirstripe $testdir/* |
26107                                 grep -c -P "^\s+$i\t")
26108                         (( count > max )) && max=$count
26109                         echo "$count stripes created on MDT$i"
26110                 done
26111
26112                 min=$($LFS getdirstripe $testdir/* |
26113                         grep -c -P "^\s+$min_index\t")
26114                 (( max - min > num * stripe_count / 10 )) ||
26115                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26116         fi
26117 }
26118
26119 most_full_mdt() {
26120         local ffree
26121         local bavail
26122         local bsize
26123         local min
26124         local min_index
26125         local tmp
26126
26127         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26128         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26129         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26130
26131         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26132         min_index=0
26133         for ((i = 1; i < ${#ffree[@]}; i++)); do
26134                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26135                 (( tmp < min )) && min=$tmp && min_index=$i
26136         done
26137
26138         echo -n $min_index
26139 }
26140
26141 test_413a() {
26142         [ $MDSCOUNT -lt 2 ] &&
26143                 skip "We need at least 2 MDTs for this test"
26144
26145         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26146                 skip "Need server version at least 2.12.52"
26147
26148         local stripe_count
26149
26150         generate_uneven_mdts 100
26151         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26152                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26153                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26154                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26155                         error "mkdir failed"
26156                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26157         done
26158 }
26159 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26160
26161 test_413b() {
26162         [ $MDSCOUNT -lt 2 ] &&
26163                 skip "We need at least 2 MDTs for this test"
26164
26165         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26166                 skip "Need server version at least 2.12.52"
26167
26168         local testdir
26169         local stripe_count
26170
26171         generate_uneven_mdts 100
26172         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26173                 testdir=$DIR/$tdir-s$stripe_count
26174                 mkdir $testdir || error "mkdir $testdir failed"
26175                 mkdir $testdir/rr || error "mkdir rr failed"
26176                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26177                         error "mkdir qos failed"
26178                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26179                         $testdir/rr || error "setdirstripe rr failed"
26180                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26181                         error "setdirstripe failed"
26182                 test_qos_mkdir "mkdir" $stripe_count
26183         done
26184 }
26185 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26186
26187 test_413c() {
26188         (( $MDSCOUNT >= 2 )) ||
26189                 skip "We need at least 2 MDTs for this test"
26190
26191         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26192                 skip "Need server version at least 2.14.51"
26193
26194         local testdir
26195         local inherit
26196         local inherit_rr
26197
26198         testdir=$DIR/${tdir}-s1
26199         mkdir $testdir || error "mkdir $testdir failed"
26200         mkdir $testdir/rr || error "mkdir rr failed"
26201         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26202         # default max_inherit is -1, default max_inherit_rr is 0
26203         $LFS setdirstripe -D -c 1 $testdir/rr ||
26204                 error "setdirstripe rr failed"
26205         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26206                 error "setdirstripe qos failed"
26207         test_qos_mkdir "mkdir" 1
26208
26209         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26210         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26211         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26212         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26213         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26214
26215         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26216         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26217         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26218         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26219         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26220         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26221         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26222                 error "level2 shouldn't have default LMV" || true
26223 }
26224 run_test 413c "mkdir with default LMV max inherit rr"
26225
26226 test_413d() {
26227         (( MDSCOUNT >= 2 )) ||
26228                 skip "We need at least 2 MDTs for this test"
26229
26230         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26231                 skip "Need server version at least 2.14.51"
26232
26233         local lmv_qos_threshold_rr
26234
26235         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26236                 head -n1)
26237         stack_trap "$LCTL set_param \
26238                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26239
26240         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26241         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26242         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26243                 error "$tdir shouldn't have default LMV"
26244         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26245                 error "mkdir sub failed"
26246
26247         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26248
26249         (( count == 100 )) || error "$count subdirs on MDT0"
26250 }
26251 run_test 413d "inherit ROOT default LMV"
26252
26253 test_413e() {
26254         (( MDSCOUNT >= 2 )) ||
26255                 skip "We need at least 2 MDTs for this test"
26256         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26257                 skip "Need server version at least 2.14.55"
26258
26259         local testdir=$DIR/$tdir
26260         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26261         local max_inherit
26262         local sub_max_inherit
26263
26264         mkdir -p $testdir || error "failed to create $testdir"
26265
26266         # set default max-inherit to -1 if stripe count is 0 or 1
26267         $LFS setdirstripe -D -c 1 $testdir ||
26268                 error "failed to set default LMV"
26269         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26270         (( max_inherit == -1 )) ||
26271                 error "wrong max_inherit value $max_inherit"
26272
26273         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26274         $LFS setdirstripe -D -c -1 $testdir ||
26275                 error "failed to set default LMV"
26276         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26277         (( max_inherit > 0 )) ||
26278                 error "wrong max_inherit value $max_inherit"
26279
26280         # and the subdir will decrease the max_inherit by 1
26281         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26282         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26283         (( sub_max_inherit == max_inherit - 1)) ||
26284                 error "wrong max-inherit of subdir $sub_max_inherit"
26285
26286         # check specified --max-inherit and warning message
26287         stack_trap "rm -f $tmpfile"
26288         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26289                 error "failed to set default LMV"
26290         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26291         (( max_inherit == -1 )) ||
26292                 error "wrong max_inherit value $max_inherit"
26293
26294         # check the warning messages
26295         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26296                 error "failed to detect warning string"
26297         fi
26298 }
26299 run_test 413e "check default max-inherit value"
26300
26301 test_fs_dmv_inherit()
26302 {
26303         local testdir=$DIR/$tdir
26304
26305         local count
26306         local inherit
26307         local inherit_rr
26308
26309         for i in 1 2 3; do
26310                 mkdir $testdir || error "mkdir $testdir failed"
26311                 count=$($LFS getdirstripe -D -c $testdir)
26312                 (( count == 1 )) ||
26313                         error "$testdir default LMV count mismatch $count != 1"
26314                 inherit=$($LFS getdirstripe -D -X $testdir)
26315                 (( inherit == 3 - i )) ||
26316                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26317                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26318                 (( inherit_rr == 3 - i )) ||
26319                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26320                 testdir=$testdir/sub
26321         done
26322
26323         mkdir $testdir || error "mkdir $testdir failed"
26324         count=$($LFS getdirstripe -D -c $testdir)
26325         (( count == 0 )) ||
26326                 error "$testdir default LMV count not zero: $count"
26327 }
26328
26329 test_413f() {
26330         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26331
26332         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26333                 skip "Need server version at least 2.14.55"
26334
26335         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26336                 error "dump $DIR default LMV failed"
26337         stack_trap "setfattr --restore=$TMP/dmv.ea"
26338
26339         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26340                 error "set $DIR default LMV failed"
26341
26342         test_fs_dmv_inherit
26343 }
26344 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26345
26346 test_413g() {
26347         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26348
26349         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26350         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26351                 error "dump $DIR default LMV failed"
26352         stack_trap "setfattr --restore=$TMP/dmv.ea"
26353
26354         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26355                 error "set $DIR default LMV failed"
26356
26357         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26358                 error "mount $MOUNT2 failed"
26359         stack_trap "umount_client $MOUNT2"
26360
26361         local saved_DIR=$DIR
26362
26363         export DIR=$MOUNT2
26364
26365         stack_trap "export DIR=$saved_DIR"
26366
26367         # first check filesystem-wide default LMV inheritance
26368         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26369
26370         # then check subdirs are spread to all MDTs
26371         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26372
26373         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26374
26375         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26376 }
26377 run_test 413g "enforce ROOT default LMV on subdir mount"
26378
26379 test_413h() {
26380         (( MDSCOUNT >= 2 )) ||
26381                 skip "We need at least 2 MDTs for this test"
26382
26383         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26384                 skip "Need server version at least 2.15.50.6"
26385
26386         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26387
26388         stack_trap "$LCTL set_param \
26389                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26390         $LCTL set_param lmv.*.qos_maxage=1
26391
26392         local depth=5
26393         local rr_depth=4
26394         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26395         local count=$((MDSCOUNT * 20))
26396
26397         generate_uneven_mdts 50
26398
26399         mkdir -p $dir || error "mkdir $dir failed"
26400         stack_trap "rm -rf $dir"
26401         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26402                 --max-inherit-rr=$rr_depth $dir
26403
26404         for ((d=0; d < depth + 2; d++)); do
26405                 log "dir=$dir:"
26406                 for ((sub=0; sub < count; sub++)); do
26407                         mkdir $dir/d$sub
26408                 done
26409                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26410                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26411                 # subdirs within $rr_depth should be created round-robin
26412                 if (( d < rr_depth )); then
26413                         (( ${num[0]} != count )) ||
26414                                 error "all objects created on MDT ${num[1]}"
26415                 fi
26416
26417                 dir=$dir/d0
26418         done
26419 }
26420 run_test 413h "don't stick to parent for round-robin dirs"
26421
26422 test_413z() {
26423         local pids=""
26424         local subdir
26425         local pid
26426
26427         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26428                 unlinkmany $subdir/f. $TEST413_COUNT &
26429                 pids="$pids $!"
26430         done
26431
26432         for pid in $pids; do
26433                 wait $pid
26434         done
26435 }
26436 run_test 413z "413 test cleanup"
26437
26438 test_414() {
26439 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26440         $LCTL set_param fail_loc=0x80000521
26441         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26442         rm -f $DIR/$tfile
26443 }
26444 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26445
26446 test_415() {
26447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26448         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26449                 skip "Need server version at least 2.11.52"
26450
26451         # LU-11102
26452         local total
26453         local setattr_pid
26454         local start_time
26455         local end_time
26456         local duration
26457
26458         total=500
26459         # this test may be slow on ZFS
26460         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26461
26462         # though this test is designed for striped directory, let's test normal
26463         # directory too since lock is always saved as CoS lock.
26464         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26465         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26466
26467         (
26468                 while true; do
26469                         touch $DIR/$tdir
26470                 done
26471         ) &
26472         setattr_pid=$!
26473
26474         start_time=$(date +%s)
26475         for i in $(seq $total); do
26476                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26477                         > /dev/null
26478         done
26479         end_time=$(date +%s)
26480         duration=$((end_time - start_time))
26481
26482         kill -9 $setattr_pid
26483
26484         echo "rename $total files took $duration sec"
26485         [ $duration -lt 100 ] || error "rename took $duration sec"
26486 }
26487 run_test 415 "lock revoke is not missing"
26488
26489 test_416() {
26490         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26491                 skip "Need server version at least 2.11.55"
26492
26493         # define OBD_FAIL_OSD_TXN_START    0x19a
26494         do_facet mds1 lctl set_param fail_loc=0x19a
26495
26496         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26497
26498         true
26499 }
26500 run_test 416 "transaction start failure won't cause system hung"
26501
26502 cleanup_417() {
26503         trap 0
26504         do_nodes $(comma_list $(mdts_nodes)) \
26505                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26506         do_nodes $(comma_list $(mdts_nodes)) \
26507                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26508         do_nodes $(comma_list $(mdts_nodes)) \
26509                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26510 }
26511
26512 test_417() {
26513         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26514         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26515                 skip "Need MDS version at least 2.11.56"
26516
26517         trap cleanup_417 RETURN EXIT
26518
26519         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26520         do_nodes $(comma_list $(mdts_nodes)) \
26521                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26522         $LFS migrate -m 0 $DIR/$tdir.1 &&
26523                 error "migrate dir $tdir.1 should fail"
26524
26525         do_nodes $(comma_list $(mdts_nodes)) \
26526                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26527         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26528                 error "create remote dir $tdir.2 should fail"
26529
26530         do_nodes $(comma_list $(mdts_nodes)) \
26531                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26532         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26533                 error "create striped dir $tdir.3 should fail"
26534         true
26535 }
26536 run_test 417 "disable remote dir, striped dir and dir migration"
26537
26538 # Checks that the outputs of df [-i] and lfs df [-i] match
26539 #
26540 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26541 check_lfs_df() {
26542         local dir=$2
26543         local inodes
26544         local df_out
26545         local lfs_df_out
26546         local count
26547         local passed=false
26548
26549         # blocks or inodes
26550         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26551
26552         for count in {1..100}; do
26553                 do_nodes "$CLIENTS" \
26554                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26555                 sync; sleep 0.2
26556
26557                 # read the lines of interest
26558                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26559                         error "df $inodes $dir | tail -n +2 failed"
26560                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26561                         error "lfs df $inodes $dir | grep summary: failed"
26562
26563                 # skip first substrings of each output as they are different
26564                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26565                 # compare the two outputs
26566                 passed=true
26567                 #  skip "available" on MDT until LU-13997 is fixed.
26568                 #for i in {1..5}; do
26569                 for i in 1 2 4 5; do
26570                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26571                 done
26572                 $passed && break
26573         done
26574
26575         if ! $passed; then
26576                 df -P $inodes $dir
26577                 echo
26578                 lfs df $inodes $dir
26579                 error "df and lfs df $1 output mismatch: "      \
26580                       "df ${inodes}: ${df_out[*]}, "            \
26581                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26582         fi
26583 }
26584
26585 test_418() {
26586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26587
26588         local dir=$DIR/$tdir
26589         local numfiles=$((RANDOM % 4096 + 2))
26590         local numblocks=$((RANDOM % 256 + 1))
26591
26592         wait_delete_completed
26593         test_mkdir $dir
26594
26595         # check block output
26596         check_lfs_df blocks $dir
26597         # check inode output
26598         check_lfs_df inodes $dir
26599
26600         # create a single file and retest
26601         echo "Creating a single file and testing"
26602         createmany -o $dir/$tfile- 1 &>/dev/null ||
26603                 error "creating 1 file in $dir failed"
26604         check_lfs_df blocks $dir
26605         check_lfs_df inodes $dir
26606
26607         # create a random number of files
26608         echo "Creating $((numfiles - 1)) files and testing"
26609         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26610                 error "creating $((numfiles - 1)) files in $dir failed"
26611
26612         # write a random number of blocks to the first test file
26613         echo "Writing $numblocks 4K blocks and testing"
26614         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26615                 count=$numblocks &>/dev/null ||
26616                 error "dd to $dir/${tfile}-0 failed"
26617
26618         # retest
26619         check_lfs_df blocks $dir
26620         check_lfs_df inodes $dir
26621
26622         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26623                 error "unlinking $numfiles files in $dir failed"
26624 }
26625 run_test 418 "df and lfs df outputs match"
26626
26627 test_419()
26628 {
26629         local dir=$DIR/$tdir
26630
26631         mkdir -p $dir
26632         touch $dir/file
26633
26634         cancel_lru_locks mdc
26635
26636         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26637         $LCTL set_param fail_loc=0x1410
26638         cat $dir/file
26639         $LCTL set_param fail_loc=0
26640         rm -rf $dir
26641 }
26642 run_test 419 "Verify open file by name doesn't crash kernel"
26643
26644 test_420()
26645 {
26646         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26647                 skip "Need MDS version at least 2.12.53"
26648
26649         local SAVE_UMASK=$(umask)
26650         local dir=$DIR/$tdir
26651         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26652
26653         mkdir -p $dir
26654         umask 0000
26655         mkdir -m03777 $dir/testdir
26656         ls -dn $dir/testdir
26657         # Need to remove trailing '.' when SELinux is enabled
26658         local dirperms=$(ls -dn $dir/testdir |
26659                          awk '{ sub(/\.$/, "", $1); print $1}')
26660         [ $dirperms == "drwxrwsrwt" ] ||
26661                 error "incorrect perms on $dir/testdir"
26662
26663         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26664                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26665         ls -n $dir/testdir/testfile
26666         local fileperms=$(ls -n $dir/testdir/testfile |
26667                           awk '{ sub(/\.$/, "", $1); print $1}')
26668         [ $fileperms == "-rwxr-xr-x" ] ||
26669                 error "incorrect perms on $dir/testdir/testfile"
26670
26671         umask $SAVE_UMASK
26672 }
26673 run_test 420 "clear SGID bit on non-directories for non-members"
26674
26675 test_421a() {
26676         local cnt
26677         local fid1
26678         local fid2
26679
26680         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26681                 skip "Need MDS version at least 2.12.54"
26682
26683         test_mkdir $DIR/$tdir
26684         createmany -o $DIR/$tdir/f 3
26685         cnt=$(ls -1 $DIR/$tdir | wc -l)
26686         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26687
26688         fid1=$(lfs path2fid $DIR/$tdir/f1)
26689         fid2=$(lfs path2fid $DIR/$tdir/f2)
26690         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26691
26692         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26693         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26694
26695         cnt=$(ls -1 $DIR/$tdir | wc -l)
26696         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26697
26698         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26699         createmany -o $DIR/$tdir/f 3
26700         cnt=$(ls -1 $DIR/$tdir | wc -l)
26701         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26702
26703         fid1=$(lfs path2fid $DIR/$tdir/f1)
26704         fid2=$(lfs path2fid $DIR/$tdir/f2)
26705         echo "remove using fsname $FSNAME"
26706         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26707
26708         cnt=$(ls -1 $DIR/$tdir | wc -l)
26709         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26710 }
26711 run_test 421a "simple rm by fid"
26712
26713 test_421b() {
26714         local cnt
26715         local FID1
26716         local FID2
26717
26718         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26719                 skip "Need MDS version at least 2.12.54"
26720
26721         test_mkdir $DIR/$tdir
26722         createmany -o $DIR/$tdir/f 3
26723         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26724         MULTIPID=$!
26725
26726         FID1=$(lfs path2fid $DIR/$tdir/f1)
26727         FID2=$(lfs path2fid $DIR/$tdir/f2)
26728         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26729
26730         kill -USR1 $MULTIPID
26731         wait
26732
26733         cnt=$(ls $DIR/$tdir | wc -l)
26734         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26735 }
26736 run_test 421b "rm by fid on open file"
26737
26738 test_421c() {
26739         local cnt
26740         local FIDS
26741
26742         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26743                 skip "Need MDS version at least 2.12.54"
26744
26745         test_mkdir $DIR/$tdir
26746         createmany -o $DIR/$tdir/f 3
26747         touch $DIR/$tdir/$tfile
26748         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26749         cnt=$(ls -1 $DIR/$tdir | wc -l)
26750         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26751
26752         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26753         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26754
26755         cnt=$(ls $DIR/$tdir | wc -l)
26756         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26757 }
26758 run_test 421c "rm by fid against hardlinked files"
26759
26760 test_421d() {
26761         local cnt
26762         local FIDS
26763
26764         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26765                 skip "Need MDS version at least 2.12.54"
26766
26767         test_mkdir $DIR/$tdir
26768         createmany -o $DIR/$tdir/f 4097
26769         cnt=$(ls -1 $DIR/$tdir | wc -l)
26770         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26771
26772         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26773         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26774
26775         cnt=$(ls $DIR/$tdir | wc -l)
26776         rm -rf $DIR/$tdir
26777         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26778 }
26779 run_test 421d "rmfid en masse"
26780
26781 test_421e() {
26782         local cnt
26783         local FID
26784
26785         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26786         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26787                 skip "Need MDS version at least 2.12.54"
26788
26789         mkdir -p $DIR/$tdir
26790         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26791         createmany -o $DIR/$tdir/striped_dir/f 512
26792         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26793         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26794
26795         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26796                 sed "s/[/][^:]*://g")
26797         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26798
26799         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26800         rm -rf $DIR/$tdir
26801         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26802 }
26803 run_test 421e "rmfid in DNE"
26804
26805 test_421f() {
26806         local cnt
26807         local FID
26808
26809         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26810                 skip "Need MDS version at least 2.12.54"
26811
26812         test_mkdir $DIR/$tdir
26813         touch $DIR/$tdir/f
26814         cnt=$(ls -1 $DIR/$tdir | wc -l)
26815         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26816
26817         FID=$(lfs path2fid $DIR/$tdir/f)
26818         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26819         # rmfid should fail
26820         cnt=$(ls -1 $DIR/$tdir | wc -l)
26821         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26822
26823         chmod a+rw $DIR/$tdir
26824         ls -la $DIR/$tdir
26825         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26826         # rmfid should fail
26827         cnt=$(ls -1 $DIR/$tdir | wc -l)
26828         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26829
26830         rm -f $DIR/$tdir/f
26831         $RUNAS touch $DIR/$tdir/f
26832         FID=$(lfs path2fid $DIR/$tdir/f)
26833         echo "rmfid as root"
26834         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26835         cnt=$(ls -1 $DIR/$tdir | wc -l)
26836         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26837
26838         rm -f $DIR/$tdir/f
26839         $RUNAS touch $DIR/$tdir/f
26840         cnt=$(ls -1 $DIR/$tdir | wc -l)
26841         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26842         FID=$(lfs path2fid $DIR/$tdir/f)
26843         # rmfid w/o user_fid2path mount option should fail
26844         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26845         cnt=$(ls -1 $DIR/$tdir | wc -l)
26846         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26847
26848         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26849         stack_trap "rmdir $tmpdir"
26850         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26851                 error "failed to mount client'"
26852         stack_trap "umount_client $tmpdir"
26853
26854         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26855         # rmfid should succeed
26856         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26857         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26858
26859         # rmfid shouldn't allow to remove files due to dir's permission
26860         chmod a+rwx $tmpdir/$tdir
26861         touch $tmpdir/$tdir/f
26862         ls -la $tmpdir/$tdir
26863         FID=$(lfs path2fid $tmpdir/$tdir/f)
26864         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26865         return 0
26866 }
26867 run_test 421f "rmfid checks permissions"
26868
26869 test_421g() {
26870         local cnt
26871         local FIDS
26872
26873         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26874         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26875                 skip "Need MDS version at least 2.12.54"
26876
26877         mkdir -p $DIR/$tdir
26878         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26879         createmany -o $DIR/$tdir/striped_dir/f 512
26880         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26881         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26882
26883         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26884                 sed "s/[/][^:]*://g")
26885
26886         rm -f $DIR/$tdir/striped_dir/f1*
26887         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26888         removed=$((512 - cnt))
26889
26890         # few files have been just removed, so we expect
26891         # rmfid to fail on their fids
26892         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26893         [ $removed != $errors ] && error "$errors != $removed"
26894
26895         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26896         rm -rf $DIR/$tdir
26897         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26898 }
26899 run_test 421g "rmfid to return errors properly"
26900
26901 test_422() {
26902         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26903         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26904         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26905         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26906         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26907
26908         local amc=$(at_max_get client)
26909         local amo=$(at_max_get mds1)
26910         local timeout=`lctl get_param -n timeout`
26911
26912         at_max_set 0 client
26913         at_max_set 0 mds1
26914
26915 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26916         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26917                         fail_val=$(((2*timeout + 10)*1000))
26918         touch $DIR/$tdir/d3/file &
26919         sleep 2
26920 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26921         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26922                         fail_val=$((2*timeout + 5))
26923         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26924         local pid=$!
26925         sleep 1
26926         kill -9 $pid
26927         sleep $((2 * timeout))
26928         echo kill $pid
26929         kill -9 $pid
26930         lctl mark touch
26931         touch $DIR/$tdir/d2/file3
26932         touch $DIR/$tdir/d2/file4
26933         touch $DIR/$tdir/d2/file5
26934
26935         wait
26936         at_max_set $amc client
26937         at_max_set $amo mds1
26938
26939         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26940         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26941                 error "Watchdog is always throttled"
26942 }
26943 run_test 422 "kill a process with RPC in progress"
26944
26945 stat_test() {
26946     df -h $MOUNT &
26947     df -h $MOUNT &
26948     df -h $MOUNT &
26949     df -h $MOUNT &
26950     df -h $MOUNT &
26951     df -h $MOUNT &
26952 }
26953
26954 test_423() {
26955     local _stats
26956     # ensure statfs cache is expired
26957     sleep 2;
26958
26959     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26960     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26961
26962     return 0
26963 }
26964 run_test 423 "statfs should return a right data"
26965
26966 test_424() {
26967 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26968         $LCTL set_param fail_loc=0x80000522
26969         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26970         rm -f $DIR/$tfile
26971 }
26972 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26973
26974 test_425() {
26975         test_mkdir -c -1 $DIR/$tdir
26976         $LFS setstripe -c -1 $DIR/$tdir
26977
26978         lru_resize_disable "" 100
26979         stack_trap "lru_resize_enable" EXIT
26980
26981         sleep 5
26982
26983         for i in $(seq $((MDSCOUNT * 125))); do
26984                 local t=$DIR/$tdir/$tfile_$i
26985
26986                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26987                         error_noexit "Create file $t"
26988         done
26989         stack_trap "rm -rf $DIR/$tdir" EXIT
26990
26991         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26992                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26993                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26994
26995                 [ $lock_count -le $lru_size ] ||
26996                         error "osc lock count $lock_count > lru size $lru_size"
26997         done
26998
26999         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27000                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27001                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27002
27003                 [ $lock_count -le $lru_size ] ||
27004                         error "mdc lock count $lock_count > lru size $lru_size"
27005         done
27006 }
27007 run_test 425 "lock count should not exceed lru size"
27008
27009 test_426() {
27010         splice-test -r $DIR/$tfile
27011         splice-test -rd $DIR/$tfile
27012         splice-test $DIR/$tfile
27013         splice-test -d $DIR/$tfile
27014 }
27015 run_test 426 "splice test on Lustre"
27016
27017 test_427() {
27018         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27019         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27020                 skip "Need MDS version at least 2.12.4"
27021         local log
27022
27023         mkdir $DIR/$tdir
27024         mkdir $DIR/$tdir/1
27025         mkdir $DIR/$tdir/2
27026         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27027         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27028
27029         $LFS getdirstripe $DIR/$tdir/1/dir
27030
27031         #first setfattr for creating updatelog
27032         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27033
27034 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27035         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27036         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27037         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27038
27039         sleep 2
27040         fail mds2
27041         wait_recovery_complete mds2 $((2*TIMEOUT))
27042
27043         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27044         echo $log | grep "get update log failed" &&
27045                 error "update log corruption is detected" || true
27046 }
27047 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27048
27049 test_428() {
27050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27051         local cache_limit=$CACHE_MAX
27052
27053         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27054         $LCTL set_param -n llite.*.max_cached_mb=64
27055
27056         mkdir $DIR/$tdir
27057         $LFS setstripe -c 1 $DIR/$tdir
27058         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27059         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27060         #test write
27061         for f in $(seq 4); do
27062                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27063         done
27064         wait
27065
27066         cancel_lru_locks osc
27067         # Test read
27068         for f in $(seq 4); do
27069                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27070         done
27071         wait
27072 }
27073 run_test 428 "large block size IO should not hang"
27074
27075 test_429() { # LU-7915 / LU-10948
27076         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27077         local testfile=$DIR/$tfile
27078         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27079         local new_flag=1
27080         local first_rpc
27081         local second_rpc
27082         local third_rpc
27083
27084         $LCTL get_param $ll_opencache_threshold_count ||
27085                 skip "client does not have opencache parameter"
27086
27087         set_opencache $new_flag
27088         stack_trap "restore_opencache"
27089         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27090                 error "enable opencache failed"
27091         touch $testfile
27092         # drop MDC DLM locks
27093         cancel_lru_locks mdc
27094         # clear MDC RPC stats counters
27095         $LCTL set_param $mdc_rpcstats=clear
27096
27097         # According to the current implementation, we need to run 3 times
27098         # open & close file to verify if opencache is enabled correctly.
27099         # 1st, RPCs are sent for lookup/open and open handle is released on
27100         #      close finally.
27101         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27102         #      so open handle won't be released thereafter.
27103         # 3rd, No RPC is sent out.
27104         $MULTIOP $testfile oc || error "multiop failed"
27105         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27106         echo "1st: $first_rpc RPCs in flight"
27107
27108         $MULTIOP $testfile oc || error "multiop failed"
27109         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27110         echo "2nd: $second_rpc RPCs in flight"
27111
27112         $MULTIOP $testfile oc || error "multiop failed"
27113         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27114         echo "3rd: $third_rpc RPCs in flight"
27115
27116         #verify no MDC RPC is sent
27117         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27118 }
27119 run_test 429 "verify if opencache flag on client side does work"
27120
27121 lseek_test_430() {
27122         local offset
27123         local file=$1
27124
27125         # data at [200K, 400K)
27126         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27127                 error "256K->512K dd fails"
27128         # data at [2M, 3M)
27129         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27130                 error "2M->3M dd fails"
27131         # data at [4M, 5M)
27132         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27133                 error "4M->5M dd fails"
27134         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27135         # start at first component hole #1
27136         printf "Seeking hole from 1000 ... "
27137         offset=$(lseek_test -l 1000 $file)
27138         echo $offset
27139         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27140         printf "Seeking data from 1000 ... "
27141         offset=$(lseek_test -d 1000 $file)
27142         echo $offset
27143         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27144
27145         # start at first component data block
27146         printf "Seeking hole from 300000 ... "
27147         offset=$(lseek_test -l 300000 $file)
27148         echo $offset
27149         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27150         printf "Seeking data from 300000 ... "
27151         offset=$(lseek_test -d 300000 $file)
27152         echo $offset
27153         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27154
27155         # start at the first component but beyond end of object size
27156         printf "Seeking hole from 1000000 ... "
27157         offset=$(lseek_test -l 1000000 $file)
27158         echo $offset
27159         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27160         printf "Seeking data from 1000000 ... "
27161         offset=$(lseek_test -d 1000000 $file)
27162         echo $offset
27163         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27164
27165         # start at second component stripe 2 (empty file)
27166         printf "Seeking hole from 1500000 ... "
27167         offset=$(lseek_test -l 1500000 $file)
27168         echo $offset
27169         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27170         printf "Seeking data from 1500000 ... "
27171         offset=$(lseek_test -d 1500000 $file)
27172         echo $offset
27173         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27174
27175         # start at second component stripe 1 (all data)
27176         printf "Seeking hole from 3000000 ... "
27177         offset=$(lseek_test -l 3000000 $file)
27178         echo $offset
27179         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27180         printf "Seeking data from 3000000 ... "
27181         offset=$(lseek_test -d 3000000 $file)
27182         echo $offset
27183         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27184
27185         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27186                 error "2nd dd fails"
27187         echo "Add data block at 640K...1280K"
27188
27189         # start at before new data block, in hole
27190         printf "Seeking hole from 600000 ... "
27191         offset=$(lseek_test -l 600000 $file)
27192         echo $offset
27193         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27194         printf "Seeking data from 600000 ... "
27195         offset=$(lseek_test -d 600000 $file)
27196         echo $offset
27197         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27198
27199         # start at the first component new data block
27200         printf "Seeking hole from 1000000 ... "
27201         offset=$(lseek_test -l 1000000 $file)
27202         echo $offset
27203         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27204         printf "Seeking data from 1000000 ... "
27205         offset=$(lseek_test -d 1000000 $file)
27206         echo $offset
27207         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27208
27209         # start at second component stripe 2, new data
27210         printf "Seeking hole from 1200000 ... "
27211         offset=$(lseek_test -l 1200000 $file)
27212         echo $offset
27213         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27214         printf "Seeking data from 1200000 ... "
27215         offset=$(lseek_test -d 1200000 $file)
27216         echo $offset
27217         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27218
27219         # start beyond file end
27220         printf "Using offset > filesize ... "
27221         lseek_test -l 4000000 $file && error "lseek should fail"
27222         printf "Using offset > filesize ... "
27223         lseek_test -d 4000000 $file && error "lseek should fail"
27224
27225         printf "Done\n\n"
27226 }
27227
27228 test_430a() {
27229         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27230                 skip "MDT does not support SEEK_HOLE"
27231
27232         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27233                 skip "OST does not support SEEK_HOLE"
27234
27235         local file=$DIR/$tdir/$tfile
27236
27237         mkdir -p $DIR/$tdir
27238
27239         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27240         # OST stripe #1 will have continuous data at [1M, 3M)
27241         # OST stripe #2 is empty
27242         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27243         lseek_test_430 $file
27244         rm $file
27245         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27246         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27247         lseek_test_430 $file
27248         rm $file
27249         $LFS setstripe -c2 -S 512K $file
27250         echo "Two stripes, stripe size 512K"
27251         lseek_test_430 $file
27252         rm $file
27253         # FLR with stale mirror
27254         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27255                        -N -c2 -S 1M $file
27256         echo "Mirrored file:"
27257         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27258         echo "Plain 2 stripes 1M"
27259         lseek_test_430 $file
27260         rm $file
27261 }
27262 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27263
27264 test_430b() {
27265         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27266                 skip "OST does not support SEEK_HOLE"
27267
27268         local offset
27269         local file=$DIR/$tdir/$tfile
27270
27271         mkdir -p $DIR/$tdir
27272         # Empty layout lseek should fail
27273         $MCREATE $file
27274         # seek from 0
27275         printf "Seeking hole from 0 ... "
27276         lseek_test -l 0 $file && error "lseek should fail"
27277         printf "Seeking data from 0 ... "
27278         lseek_test -d 0 $file && error "lseek should fail"
27279         rm $file
27280
27281         # 1M-hole file
27282         $LFS setstripe -E 1M -c2 -E eof $file
27283         $TRUNCATE $file 1048576
27284         printf "Seeking hole from 1000000 ... "
27285         offset=$(lseek_test -l 1000000 $file)
27286         echo $offset
27287         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27288         printf "Seeking data from 1000000 ... "
27289         lseek_test -d 1000000 $file && error "lseek should fail"
27290         rm $file
27291
27292         # full component followed by non-inited one
27293         $LFS setstripe -E 1M -c2 -E eof $file
27294         dd if=/dev/urandom of=$file bs=1M count=1
27295         printf "Seeking hole from 1000000 ... "
27296         offset=$(lseek_test -l 1000000 $file)
27297         echo $offset
27298         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27299         printf "Seeking hole from 1048576 ... "
27300         lseek_test -l 1048576 $file && error "lseek should fail"
27301         # init second component and truncate back
27302         echo "123" >> $file
27303         $TRUNCATE $file 1048576
27304         printf "Seeking hole from 1000000 ... "
27305         offset=$(lseek_test -l 1000000 $file)
27306         echo $offset
27307         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27308         printf "Seeking hole from 1048576 ... "
27309         lseek_test -l 1048576 $file && error "lseek should fail"
27310         # boundary checks for big values
27311         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27312         offset=$(lseek_test -d 0 $file.10g)
27313         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27314         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27315         offset=$(lseek_test -d 0 $file.100g)
27316         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27317         return 0
27318 }
27319 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27320
27321 test_430c() {
27322         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27323                 skip "OST does not support SEEK_HOLE"
27324
27325         local file=$DIR/$tdir/$tfile
27326         local start
27327
27328         mkdir -p $DIR/$tdir
27329         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27330
27331         # cp version 8.33+ prefers lseek over fiemap
27332         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27333                 start=$SECONDS
27334                 time cp $file /dev/null
27335                 (( SECONDS - start < 5 )) ||
27336                         error "cp: too long runtime $((SECONDS - start))"
27337
27338         fi
27339         # tar version 1.29+ supports SEEK_HOLE/DATA
27340         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27341                 start=$SECONDS
27342                 time tar cS $file - | cat > /dev/null
27343                 (( SECONDS - start < 5 )) ||
27344                         error "tar: too long runtime $((SECONDS - start))"
27345         fi
27346 }
27347 run_test 430c "lseek: external tools check"
27348
27349 test_431() { # LU-14187
27350         local file=$DIR/$tdir/$tfile
27351
27352         mkdir -p $DIR/$tdir
27353         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27354         dd if=/dev/urandom of=$file bs=4k count=1
27355         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27356         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27357         #define OBD_FAIL_OST_RESTART_IO 0x251
27358         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27359         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27360         cp $file $file.0
27361         cancel_lru_locks
27362         sync_all_data
27363         echo 3 > /proc/sys/vm/drop_caches
27364         diff  $file $file.0 || error "data diff"
27365 }
27366 run_test 431 "Restart transaction for IO"
27367
27368 cleanup_test_432() {
27369         do_facet mgs $LCTL nodemap_activate 0
27370         wait_nm_sync active
27371 }
27372
27373 test_432() {
27374         local tmpdir=$TMP/dir432
27375
27376         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27377                 skip "Need MDS version at least 2.14.52"
27378
27379         stack_trap cleanup_test_432 EXIT
27380         mkdir $DIR/$tdir
27381         mkdir $tmpdir
27382
27383         do_facet mgs $LCTL nodemap_activate 1
27384         wait_nm_sync active
27385         do_facet mgs $LCTL nodemap_modify --name default \
27386                 --property admin --value 1
27387         do_facet mgs $LCTL nodemap_modify --name default \
27388                 --property trusted --value 1
27389         cancel_lru_locks mdc
27390         wait_nm_sync default admin_nodemap
27391         wait_nm_sync default trusted_nodemap
27392
27393         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27394                grep -ci "Operation not permitted") -ne 0 ]; then
27395                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27396         fi
27397 }
27398 run_test 432 "mv dir from outside Lustre"
27399
27400 test_433() {
27401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27402
27403         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27404                 skip "inode cache not supported"
27405
27406         $LCTL set_param llite.*.inode_cache=0
27407         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27408
27409         local count=256
27410         local before
27411         local after
27412
27413         cancel_lru_locks mdc
27414         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27415         createmany -m $DIR/$tdir/f $count
27416         createmany -d $DIR/$tdir/d $count
27417         ls -l $DIR/$tdir > /dev/null
27418         stack_trap "rm -rf $DIR/$tdir"
27419
27420         before=$(num_objects)
27421         cancel_lru_locks mdc
27422         after=$(num_objects)
27423
27424         # sometimes even @before is less than 2 * count
27425         while (( before - after < count )); do
27426                 sleep 1
27427                 after=$(num_objects)
27428                 wait=$((wait + 1))
27429                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27430                 if (( wait > 60 )); then
27431                         error "inode slab grew from $before to $after"
27432                 fi
27433         done
27434
27435         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27436 }
27437 run_test 433 "ldlm lock cancel releases dentries and inodes"
27438
27439 prep_801() {
27440         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27441         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27442                 skip "Need server version at least 2.9.55"
27443
27444         start_full_debug_logging
27445 }
27446
27447 post_801() {
27448         stop_full_debug_logging
27449 }
27450
27451 barrier_stat() {
27452         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27453                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27454                            awk '/The barrier for/ { print $7 }')
27455                 echo $st
27456         else
27457                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27458                 echo \'$st\'
27459         fi
27460 }
27461
27462 barrier_expired() {
27463         local expired
27464
27465         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27466                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27467                           awk '/will be expired/ { print $7 }')
27468         else
27469                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27470         fi
27471
27472         echo $expired
27473 }
27474
27475 test_801a() {
27476         prep_801
27477
27478         echo "Start barrier_freeze at: $(date)"
27479         #define OBD_FAIL_BARRIER_DELAY          0x2202
27480         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27481         # Do not reduce barrier time - See LU-11873
27482         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27483
27484         sleep 2
27485         local b_status=$(barrier_stat)
27486         echo "Got barrier status at: $(date)"
27487         [ "$b_status" = "'freezing_p1'" ] ||
27488                 error "(1) unexpected barrier status $b_status"
27489
27490         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27491         wait
27492         b_status=$(barrier_stat)
27493         [ "$b_status" = "'frozen'" ] ||
27494                 error "(2) unexpected barrier status $b_status"
27495
27496         local expired=$(barrier_expired)
27497         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27498         sleep $((expired + 3))
27499
27500         b_status=$(barrier_stat)
27501         [ "$b_status" = "'expired'" ] ||
27502                 error "(3) unexpected barrier status $b_status"
27503
27504         # Do not reduce barrier time - See LU-11873
27505         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27506                 error "(4) fail to freeze barrier"
27507
27508         b_status=$(barrier_stat)
27509         [ "$b_status" = "'frozen'" ] ||
27510                 error "(5) unexpected barrier status $b_status"
27511
27512         echo "Start barrier_thaw at: $(date)"
27513         #define OBD_FAIL_BARRIER_DELAY          0x2202
27514         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27515         do_facet mgs $LCTL barrier_thaw $FSNAME &
27516
27517         sleep 2
27518         b_status=$(barrier_stat)
27519         echo "Got barrier status at: $(date)"
27520         [ "$b_status" = "'thawing'" ] ||
27521                 error "(6) unexpected barrier status $b_status"
27522
27523         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27524         wait
27525         b_status=$(barrier_stat)
27526         [ "$b_status" = "'thawed'" ] ||
27527                 error "(7) unexpected barrier status $b_status"
27528
27529         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27530         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27531         do_facet mgs $LCTL barrier_freeze $FSNAME
27532
27533         b_status=$(barrier_stat)
27534         [ "$b_status" = "'failed'" ] ||
27535                 error "(8) unexpected barrier status $b_status"
27536
27537         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27538         do_facet mgs $LCTL barrier_thaw $FSNAME
27539
27540         post_801
27541 }
27542 run_test 801a "write barrier user interfaces and stat machine"
27543
27544 test_801b() {
27545         prep_801
27546
27547         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27548         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27549         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27550         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27551         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27552
27553         cancel_lru_locks mdc
27554
27555         # 180 seconds should be long enough
27556         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27557
27558         local b_status=$(barrier_stat)
27559         [ "$b_status" = "'frozen'" ] ||
27560                 error "(6) unexpected barrier status $b_status"
27561
27562         mkdir $DIR/$tdir/d0/d10 &
27563         mkdir_pid=$!
27564
27565         touch $DIR/$tdir/d1/f13 &
27566         touch_pid=$!
27567
27568         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27569         ln_pid=$!
27570
27571         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27572         mv_pid=$!
27573
27574         rm -f $DIR/$tdir/d4/f12 &
27575         rm_pid=$!
27576
27577         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27578
27579         # To guarantee taht the 'stat' is not blocked
27580         b_status=$(barrier_stat)
27581         [ "$b_status" = "'frozen'" ] ||
27582                 error "(8) unexpected barrier status $b_status"
27583
27584         # let above commands to run at background
27585         sleep 5
27586
27587         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27588         ps -p $touch_pid || error "(10) touch should be blocked"
27589         ps -p $ln_pid || error "(11) link should be blocked"
27590         ps -p $mv_pid || error "(12) rename should be blocked"
27591         ps -p $rm_pid || error "(13) unlink should be blocked"
27592
27593         b_status=$(barrier_stat)
27594         [ "$b_status" = "'frozen'" ] ||
27595                 error "(14) unexpected barrier status $b_status"
27596
27597         do_facet mgs $LCTL barrier_thaw $FSNAME
27598         b_status=$(barrier_stat)
27599         [ "$b_status" = "'thawed'" ] ||
27600                 error "(15) unexpected barrier status $b_status"
27601
27602         wait $mkdir_pid || error "(16) mkdir should succeed"
27603         wait $touch_pid || error "(17) touch should succeed"
27604         wait $ln_pid || error "(18) link should succeed"
27605         wait $mv_pid || error "(19) rename should succeed"
27606         wait $rm_pid || error "(20) unlink should succeed"
27607
27608         post_801
27609 }
27610 run_test 801b "modification will be blocked by write barrier"
27611
27612 test_801c() {
27613         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27614
27615         prep_801
27616
27617         stop mds2 || error "(1) Fail to stop mds2"
27618
27619         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27620
27621         local b_status=$(barrier_stat)
27622         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27623                 do_facet mgs $LCTL barrier_thaw $FSNAME
27624                 error "(2) unexpected barrier status $b_status"
27625         }
27626
27627         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27628                 error "(3) Fail to rescan barrier bitmap"
27629
27630         # Do not reduce barrier time - See LU-11873
27631         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27632
27633         b_status=$(barrier_stat)
27634         [ "$b_status" = "'frozen'" ] ||
27635                 error "(4) unexpected barrier status $b_status"
27636
27637         do_facet mgs $LCTL barrier_thaw $FSNAME
27638         b_status=$(barrier_stat)
27639         [ "$b_status" = "'thawed'" ] ||
27640                 error "(5) unexpected barrier status $b_status"
27641
27642         local devname=$(mdsdevname 2)
27643
27644         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27645
27646         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27647                 error "(7) Fail to rescan barrier bitmap"
27648
27649         post_801
27650 }
27651 run_test 801c "rescan barrier bitmap"
27652
27653 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27654 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27655 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27656 saved_MOUNT_OPTS=$MOUNT_OPTS
27657
27658 cleanup_802a() {
27659         trap 0
27660
27661         stopall
27662         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27663         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27664         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27665         MOUNT_OPTS=$saved_MOUNT_OPTS
27666         setupall
27667 }
27668
27669 test_802a() {
27670         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27671         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27672         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27673                 skip "Need server version at least 2.9.55"
27674
27675         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27676
27677         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27678
27679         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27680                 error "(2) Fail to copy"
27681
27682         trap cleanup_802a EXIT
27683
27684         # sync by force before remount as readonly
27685         sync; sync_all_data; sleep 3; sync_all_data
27686
27687         stopall
27688
27689         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27690         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27691         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27692
27693         echo "Mount the server as read only"
27694         setupall server_only || error "(3) Fail to start servers"
27695
27696         echo "Mount client without ro should fail"
27697         mount_client $MOUNT &&
27698                 error "(4) Mount client without 'ro' should fail"
27699
27700         echo "Mount client with ro should succeed"
27701         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27702         mount_client $MOUNT ||
27703                 error "(5) Mount client with 'ro' should succeed"
27704
27705         echo "Modify should be refused"
27706         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27707
27708         echo "Read should be allowed"
27709         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27710                 error "(7) Read should succeed under ro mode"
27711
27712         cleanup_802a
27713 }
27714 run_test 802a "simulate readonly device"
27715
27716 test_802b() {
27717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27718         remote_mds_nodsh && skip "remote MDS with nodsh"
27719
27720         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27721                 skip "readonly option not available"
27722
27723         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27724
27725         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27726                 error "(2) Fail to copy"
27727
27728         # write back all cached data before setting MDT to readonly
27729         cancel_lru_locks
27730         sync_all_data
27731
27732         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27733         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27734
27735         echo "Modify should be refused"
27736         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27737
27738         echo "Read should be allowed"
27739         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27740                 error "(7) Read should succeed under ro mode"
27741
27742         # disable readonly
27743         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27744 }
27745 run_test 802b "be able to set MDTs to readonly"
27746
27747 test_803a() {
27748         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27749         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27750                 skip "MDS needs to be newer than 2.10.54"
27751
27752         mkdir_on_mdt0 $DIR/$tdir
27753         # Create some objects on all MDTs to trigger related logs objects
27754         for idx in $(seq $MDSCOUNT); do
27755                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27756                         $DIR/$tdir/dir${idx} ||
27757                         error "Fail to create $DIR/$tdir/dir${idx}"
27758         done
27759
27760         sync; sleep 3
27761         wait_delete_completed # ensure old test cleanups are finished
27762         echo "before create:"
27763         $LFS df -i $MOUNT
27764         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27765
27766         for i in {1..10}; do
27767                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27768                         error "Fail to create $DIR/$tdir/foo$i"
27769         done
27770
27771         sync; sleep 3
27772         echo "after create:"
27773         $LFS df -i $MOUNT
27774         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27775
27776         # allow for an llog to be cleaned up during the test
27777         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27778                 error "before ($before_used) + 10 > after ($after_used)"
27779
27780         for i in {1..10}; do
27781                 rm -rf $DIR/$tdir/foo$i ||
27782                         error "Fail to remove $DIR/$tdir/foo$i"
27783         done
27784
27785         sleep 3 # avoid MDT return cached statfs
27786         wait_delete_completed
27787         echo "after unlink:"
27788         $LFS df -i $MOUNT
27789         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27790
27791         # allow for an llog to be created during the test
27792         [ $after_used -le $((before_used + 1)) ] ||
27793                 error "after ($after_used) > before ($before_used) + 1"
27794 }
27795 run_test 803a "verify agent object for remote object"
27796
27797 test_803b() {
27798         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27799         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27800                 skip "MDS needs to be newer than 2.13.56"
27801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27802
27803         for i in $(seq 0 $((MDSCOUNT - 1))); do
27804                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27805         done
27806
27807         local before=0
27808         local after=0
27809
27810         local tmp
27811
27812         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27813         for i in $(seq 0 $((MDSCOUNT - 1))); do
27814                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27815                         awk '/getattr/ { print $2 }')
27816                 before=$((before + tmp))
27817         done
27818         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27819         for i in $(seq 0 $((MDSCOUNT - 1))); do
27820                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27821                         awk '/getattr/ { print $2 }')
27822                 after=$((after + tmp))
27823         done
27824
27825         [ $before -eq $after ] || error "getattr count $before != $after"
27826 }
27827 run_test 803b "remote object can getattr from cache"
27828
27829 test_804() {
27830         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27831         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27832                 skip "MDS needs to be newer than 2.10.54"
27833         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27834
27835         mkdir -p $DIR/$tdir
27836         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27837                 error "Fail to create $DIR/$tdir/dir0"
27838
27839         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27840         local dev=$(mdsdevname 2)
27841
27842         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27843                 grep ${fid} || error "NOT found agent entry for dir0"
27844
27845         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27846                 error "Fail to create $DIR/$tdir/dir1"
27847
27848         touch $DIR/$tdir/dir1/foo0 ||
27849                 error "Fail to create $DIR/$tdir/dir1/foo0"
27850         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27851         local rc=0
27852
27853         for idx in $(seq $MDSCOUNT); do
27854                 dev=$(mdsdevname $idx)
27855                 do_facet mds${idx} \
27856                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27857                         grep ${fid} && rc=$idx
27858         done
27859
27860         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27861                 error "Fail to rename foo0 to foo1"
27862         if [ $rc -eq 0 ]; then
27863                 for idx in $(seq $MDSCOUNT); do
27864                         dev=$(mdsdevname $idx)
27865                         do_facet mds${idx} \
27866                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27867                         grep ${fid} && rc=$idx
27868                 done
27869         fi
27870
27871         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27872                 error "Fail to rename foo1 to foo2"
27873         if [ $rc -eq 0 ]; then
27874                 for idx in $(seq $MDSCOUNT); do
27875                         dev=$(mdsdevname $idx)
27876                         do_facet mds${idx} \
27877                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27878                         grep ${fid} && rc=$idx
27879                 done
27880         fi
27881
27882         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27883
27884         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27885                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27886         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27887                 error "Fail to rename foo2 to foo0"
27888         unlink $DIR/$tdir/dir1/foo0 ||
27889                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27890         rm -rf $DIR/$tdir/dir0 ||
27891                 error "Fail to rm $DIR/$tdir/dir0"
27892
27893         for idx in $(seq $MDSCOUNT); do
27894                 rc=0
27895
27896                 stop mds${idx}
27897                 dev=$(mdsdevname $idx)
27898                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27899                         rc=$?
27900                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27901                         error "mount mds$idx failed"
27902                 df $MOUNT > /dev/null 2>&1
27903
27904                 # e2fsck should not return error
27905                 [ $rc -eq 0 ] ||
27906                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27907         done
27908 }
27909 run_test 804 "verify agent entry for remote entry"
27910
27911 cleanup_805() {
27912         do_facet $SINGLEMDS zfs set quota=$old $fsset
27913         unlinkmany $DIR/$tdir/f- 1000000
27914         trap 0
27915 }
27916
27917 test_805() {
27918         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27919         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27920         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27921                 skip "netfree not implemented before 0.7"
27922         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27923                 skip "Need MDS version at least 2.10.57"
27924
27925         local fsset
27926         local freekb
27927         local usedkb
27928         local old
27929         local quota
27930         local pref="osd-zfs.$FSNAME-MDT0000."
27931
27932         # limit available space on MDS dataset to meet nospace issue
27933         # quickly. then ZFS 0.7.2 can use reserved space if asked
27934         # properly (using netfree flag in osd_declare_destroy()
27935         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27936         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27937                 gawk '{print $3}')
27938         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27939         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27940         let "usedkb=usedkb-freekb"
27941         let "freekb=freekb/2"
27942         if let "freekb > 5000"; then
27943                 let "freekb=5000"
27944         fi
27945         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27946         trap cleanup_805 EXIT
27947         mkdir_on_mdt0 $DIR/$tdir
27948         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27949                 error "Can't set PFL layout"
27950         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27951         rm -rf $DIR/$tdir || error "not able to remove"
27952         do_facet $SINGLEMDS zfs set quota=$old $fsset
27953         trap 0
27954 }
27955 run_test 805 "ZFS can remove from full fs"
27956
27957 # Size-on-MDS test
27958 check_lsom_data()
27959 {
27960         local file=$1
27961         local expect=$(stat -c %s $file)
27962
27963         check_lsom_size $1 $expect
27964
27965         local blocks=$($LFS getsom -b $file)
27966         expect=$(stat -c %b $file)
27967         [[ $blocks == $expect ]] ||
27968                 error "$file expected blocks: $expect, got: $blocks"
27969 }
27970
27971 check_lsom_size()
27972 {
27973         local size
27974         local expect=$2
27975
27976         cancel_lru_locks mdc
27977
27978         size=$($LFS getsom -s $1)
27979         [[ $size == $expect ]] ||
27980                 error "$file expected size: $expect, got: $size"
27981 }
27982
27983 test_806() {
27984         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27985                 skip "Need MDS version at least 2.11.52"
27986
27987         local bs=1048576
27988
27989         touch $DIR/$tfile || error "touch $tfile failed"
27990
27991         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27992         save_lustre_params client "llite.*.xattr_cache" > $save
27993         lctl set_param llite.*.xattr_cache=0
27994         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27995
27996         # single-threaded write
27997         echo "Test SOM for single-threaded write"
27998         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27999                 error "write $tfile failed"
28000         check_lsom_size $DIR/$tfile $bs
28001
28002         local num=32
28003         local size=$(($num * $bs))
28004         local offset=0
28005         local i
28006
28007         echo "Test SOM for single client multi-threaded($num) write"
28008         $TRUNCATE $DIR/$tfile 0
28009         for ((i = 0; i < $num; i++)); do
28010                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28011                 local pids[$i]=$!
28012                 offset=$((offset + $bs))
28013         done
28014         for (( i=0; i < $num; i++ )); do
28015                 wait ${pids[$i]}
28016         done
28017         check_lsom_size $DIR/$tfile $size
28018
28019         $TRUNCATE $DIR/$tfile 0
28020         for ((i = 0; i < $num; i++)); do
28021                 offset=$((offset - $bs))
28022                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28023                 local pids[$i]=$!
28024         done
28025         for (( i=0; i < $num; i++ )); do
28026                 wait ${pids[$i]}
28027         done
28028         check_lsom_size $DIR/$tfile $size
28029
28030         # multi-client writes
28031         num=$(get_node_count ${CLIENTS//,/ })
28032         size=$(($num * $bs))
28033         offset=0
28034         i=0
28035
28036         echo "Test SOM for multi-client ($num) writes"
28037         $TRUNCATE $DIR/$tfile 0
28038         for client in ${CLIENTS//,/ }; do
28039                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28040                 local pids[$i]=$!
28041                 i=$((i + 1))
28042                 offset=$((offset + $bs))
28043         done
28044         for (( i=0; i < $num; i++ )); do
28045                 wait ${pids[$i]}
28046         done
28047         check_lsom_size $DIR/$tfile $offset
28048
28049         i=0
28050         $TRUNCATE $DIR/$tfile 0
28051         for client in ${CLIENTS//,/ }; do
28052                 offset=$((offset - $bs))
28053                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28054                 local pids[$i]=$!
28055                 i=$((i + 1))
28056         done
28057         for (( i=0; i < $num; i++ )); do
28058                 wait ${pids[$i]}
28059         done
28060         check_lsom_size $DIR/$tfile $size
28061
28062         # verify truncate
28063         echo "Test SOM for truncate"
28064         $TRUNCATE $DIR/$tfile 1048576
28065         check_lsom_size $DIR/$tfile 1048576
28066         $TRUNCATE $DIR/$tfile 1234
28067         check_lsom_size $DIR/$tfile 1234
28068
28069         # verify SOM blocks count
28070         echo "Verify SOM block count"
28071         $TRUNCATE $DIR/$tfile 0
28072         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28073                 error "failed to write file $tfile"
28074         check_lsom_data $DIR/$tfile
28075 }
28076 run_test 806 "Verify Lazy Size on MDS"
28077
28078 test_807() {
28079         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28080         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28081                 skip "Need MDS version at least 2.11.52"
28082
28083         # Registration step
28084         changelog_register || error "changelog_register failed"
28085         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28086         changelog_users $SINGLEMDS | grep -q $cl_user ||
28087                 error "User $cl_user not found in changelog_users"
28088
28089         rm -rf $DIR/$tdir || error "rm $tdir failed"
28090         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28091         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28092         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28093         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28094                 error "truncate $tdir/trunc failed"
28095
28096         local bs=1048576
28097         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28098                 error "write $tfile failed"
28099
28100         # multi-client wirtes
28101         local num=$(get_node_count ${CLIENTS//,/ })
28102         local offset=0
28103         local i=0
28104
28105         echo "Test SOM for multi-client ($num) writes"
28106         touch $DIR/$tfile || error "touch $tfile failed"
28107         $TRUNCATE $DIR/$tfile 0
28108         for client in ${CLIENTS//,/ }; do
28109                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28110                 local pids[$i]=$!
28111                 i=$((i + 1))
28112                 offset=$((offset + $bs))
28113         done
28114         for (( i=0; i < $num; i++ )); do
28115                 wait ${pids[$i]}
28116         done
28117
28118         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28119         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28120         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28121         check_lsom_data $DIR/$tdir/trunc
28122         check_lsom_data $DIR/$tdir/single_dd
28123         check_lsom_data $DIR/$tfile
28124
28125         rm -rf $DIR/$tdir
28126         # Deregistration step
28127         changelog_deregister || error "changelog_deregister failed"
28128 }
28129 run_test 807 "verify LSOM syncing tool"
28130
28131 check_som_nologged()
28132 {
28133         local lines=$($LFS changelog $FSNAME-MDT0000 |
28134                 grep 'x=trusted.som' | wc -l)
28135         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28136 }
28137
28138 test_808() {
28139         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28140                 skip "Need MDS version at least 2.11.55"
28141
28142         # Registration step
28143         changelog_register || error "changelog_register failed"
28144
28145         touch $DIR/$tfile || error "touch $tfile failed"
28146         check_som_nologged
28147
28148         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28149                 error "write $tfile failed"
28150         check_som_nologged
28151
28152         $TRUNCATE $DIR/$tfile 1234
28153         check_som_nologged
28154
28155         $TRUNCATE $DIR/$tfile 1048576
28156         check_som_nologged
28157
28158         # Deregistration step
28159         changelog_deregister || error "changelog_deregister failed"
28160 }
28161 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28162
28163 check_som_nodata()
28164 {
28165         $LFS getsom $1
28166         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28167 }
28168
28169 test_809() {
28170         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28171                 skip "Need MDS version at least 2.11.56"
28172
28173         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28174                 error "failed to create DoM-only file $DIR/$tfile"
28175         touch $DIR/$tfile || error "touch $tfile failed"
28176         check_som_nodata $DIR/$tfile
28177
28178         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28179                 error "write $tfile failed"
28180         check_som_nodata $DIR/$tfile
28181
28182         $TRUNCATE $DIR/$tfile 1234
28183         check_som_nodata $DIR/$tfile
28184
28185         $TRUNCATE $DIR/$tfile 4097
28186         check_som_nodata $DIR/$file
28187 }
28188 run_test 809 "Verify no SOM xattr store for DoM-only files"
28189
28190 test_810() {
28191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28192         $GSS && skip_env "could not run with gss"
28193         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28194                 skip "OST < 2.12.58 doesn't align checksum"
28195
28196         set_checksums 1
28197         stack_trap "set_checksums $ORIG_CSUM" EXIT
28198         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28199
28200         local csum
28201         local before
28202         local after
28203         for csum in $CKSUM_TYPES; do
28204                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28205                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28206                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28207                         eval set -- $i
28208                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28209                         before=$(md5sum $DIR/$tfile)
28210                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28211                         after=$(md5sum $DIR/$tfile)
28212                         [ "$before" == "$after" ] ||
28213                                 error "$csum: $before != $after bs=$1 seek=$2"
28214                 done
28215         done
28216 }
28217 run_test 810 "partial page writes on ZFS (LU-11663)"
28218
28219 test_812a() {
28220         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28221                 skip "OST < 2.12.51 doesn't support this fail_loc"
28222
28223         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28224         # ensure ost1 is connected
28225         stat $DIR/$tfile >/dev/null || error "can't stat"
28226         wait_osc_import_state client ost1 FULL
28227         # no locks, no reqs to let the connection idle
28228         cancel_lru_locks osc
28229
28230         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28231 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28232         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28233         wait_osc_import_state client ost1 CONNECTING
28234         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28235
28236         stat $DIR/$tfile >/dev/null || error "can't stat file"
28237 }
28238 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28239
28240 test_812b() { # LU-12378
28241         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28242                 skip "OST < 2.12.51 doesn't support this fail_loc"
28243
28244         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28245         # ensure ost1 is connected
28246         stat $DIR/$tfile >/dev/null || error "can't stat"
28247         wait_osc_import_state client ost1 FULL
28248         # no locks, no reqs to let the connection idle
28249         cancel_lru_locks osc
28250
28251         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28252 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28253         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28254         wait_osc_import_state client ost1 CONNECTING
28255         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28256
28257         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28258         wait_osc_import_state client ost1 IDLE
28259 }
28260 run_test 812b "do not drop no resend request for idle connect"
28261
28262 test_812c() {
28263         local old
28264
28265         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28266
28267         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28268         $LFS getstripe $DIR/$tfile
28269         $LCTL set_param osc.*.idle_timeout=10
28270         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28271         # ensure ost1 is connected
28272         stat $DIR/$tfile >/dev/null || error "can't stat"
28273         wait_osc_import_state client ost1 FULL
28274         # no locks, no reqs to let the connection idle
28275         cancel_lru_locks osc
28276
28277 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28278         $LCTL set_param fail_loc=0x80000533
28279         sleep 15
28280         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28281 }
28282 run_test 812c "idle import vs lock enqueue race"
28283
28284 test_813() {
28285         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28286         [ -z "$file_heat_sav" ] && skip "no file heat support"
28287
28288         local readsample
28289         local writesample
28290         local readbyte
28291         local writebyte
28292         local readsample1
28293         local writesample1
28294         local readbyte1
28295         local writebyte1
28296
28297         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28298         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28299
28300         $LCTL set_param -n llite.*.file_heat=1
28301         echo "Turn on file heat"
28302         echo "Period second: $period_second, Decay percentage: $decay_pct"
28303
28304         echo "QQQQ" > $DIR/$tfile
28305         echo "QQQQ" > $DIR/$tfile
28306         echo "QQQQ" > $DIR/$tfile
28307         cat $DIR/$tfile > /dev/null
28308         cat $DIR/$tfile > /dev/null
28309         cat $DIR/$tfile > /dev/null
28310         cat $DIR/$tfile > /dev/null
28311
28312         local out=$($LFS heat_get $DIR/$tfile)
28313
28314         $LFS heat_get $DIR/$tfile
28315         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28316         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28317         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28318         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28319
28320         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28321         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28322         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28323         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28324
28325         sleep $((period_second + 3))
28326         echo "Sleep $((period_second + 3)) seconds..."
28327         # The recursion formula to calculate the heat of the file f is as
28328         # follow:
28329         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28330         # Where Hi is the heat value in the period between time points i*I and
28331         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28332         # to the weight of Ci.
28333         out=$($LFS heat_get $DIR/$tfile)
28334         $LFS heat_get $DIR/$tfile
28335         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28336         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28337         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28338         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28339
28340         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28341                 error "read sample ($readsample) is wrong"
28342         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28343                 error "write sample ($writesample) is wrong"
28344         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28345                 error "read bytes ($readbyte) is wrong"
28346         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28347                 error "write bytes ($writebyte) is wrong"
28348
28349         echo "QQQQ" > $DIR/$tfile
28350         echo "QQQQ" > $DIR/$tfile
28351         echo "QQQQ" > $DIR/$tfile
28352         cat $DIR/$tfile > /dev/null
28353         cat $DIR/$tfile > /dev/null
28354         cat $DIR/$tfile > /dev/null
28355         cat $DIR/$tfile > /dev/null
28356
28357         sleep $((period_second + 3))
28358         echo "Sleep $((period_second + 3)) seconds..."
28359
28360         out=$($LFS heat_get $DIR/$tfile)
28361         $LFS heat_get $DIR/$tfile
28362         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28363         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28364         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28365         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28366
28367         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28368                 4 * $decay_pct) / 100") -eq 1 ] ||
28369                 error "read sample ($readsample1) is wrong"
28370         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28371                 3 * $decay_pct) / 100") -eq 1 ] ||
28372                 error "write sample ($writesample1) is wrong"
28373         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28374                 20 * $decay_pct) / 100") -eq 1 ] ||
28375                 error "read bytes ($readbyte1) is wrong"
28376         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28377                 15 * $decay_pct) / 100") -eq 1 ] ||
28378                 error "write bytes ($writebyte1) is wrong"
28379
28380         echo "Turn off file heat for the file $DIR/$tfile"
28381         $LFS heat_set -o $DIR/$tfile
28382
28383         echo "QQQQ" > $DIR/$tfile
28384         echo "QQQQ" > $DIR/$tfile
28385         echo "QQQQ" > $DIR/$tfile
28386         cat $DIR/$tfile > /dev/null
28387         cat $DIR/$tfile > /dev/null
28388         cat $DIR/$tfile > /dev/null
28389         cat $DIR/$tfile > /dev/null
28390
28391         out=$($LFS heat_get $DIR/$tfile)
28392         $LFS heat_get $DIR/$tfile
28393         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28394         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28395         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28396         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28397
28398         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28399         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28400         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28401         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28402
28403         echo "Trun on file heat for the file $DIR/$tfile"
28404         $LFS heat_set -O $DIR/$tfile
28405
28406         echo "QQQQ" > $DIR/$tfile
28407         echo "QQQQ" > $DIR/$tfile
28408         echo "QQQQ" > $DIR/$tfile
28409         cat $DIR/$tfile > /dev/null
28410         cat $DIR/$tfile > /dev/null
28411         cat $DIR/$tfile > /dev/null
28412         cat $DIR/$tfile > /dev/null
28413
28414         out=$($LFS heat_get $DIR/$tfile)
28415         $LFS heat_get $DIR/$tfile
28416         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28417         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28418         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28419         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28420
28421         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28422         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28423         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28424         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28425
28426         $LFS heat_set -c $DIR/$tfile
28427         $LCTL set_param -n llite.*.file_heat=0
28428         echo "Turn off file heat support for the Lustre filesystem"
28429
28430         echo "QQQQ" > $DIR/$tfile
28431         echo "QQQQ" > $DIR/$tfile
28432         echo "QQQQ" > $DIR/$tfile
28433         cat $DIR/$tfile > /dev/null
28434         cat $DIR/$tfile > /dev/null
28435         cat $DIR/$tfile > /dev/null
28436         cat $DIR/$tfile > /dev/null
28437
28438         out=$($LFS heat_get $DIR/$tfile)
28439         $LFS heat_get $DIR/$tfile
28440         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28441         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28442         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28443         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28444
28445         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28446         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28447         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28448         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28449
28450         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28451         rm -f $DIR/$tfile
28452 }
28453 run_test 813 "File heat verfication"
28454
28455 test_814()
28456 {
28457         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28458         echo -n y >> $DIR/$tfile
28459         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28460         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28461 }
28462 run_test 814 "sparse cp works as expected (LU-12361)"
28463
28464 test_815()
28465 {
28466         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28467         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28468 }
28469 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28470
28471 test_816() {
28472         local ost1_imp=$(get_osc_import_name client ost1)
28473         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28474                          cut -d'.' -f2)
28475
28476         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28477         # ensure ost1 is connected
28478
28479         stat $DIR/$tfile >/dev/null || error "can't stat"
28480         wait_osc_import_state client ost1 FULL
28481         # no locks, no reqs to let the connection idle
28482         cancel_lru_locks osc
28483         lru_resize_disable osc
28484         local before
28485         local now
28486         before=$($LCTL get_param -n \
28487                  ldlm.namespaces.$imp_name.lru_size)
28488
28489         wait_osc_import_state client ost1 IDLE
28490         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28491         now=$($LCTL get_param -n \
28492               ldlm.namespaces.$imp_name.lru_size)
28493         [ $before == $now ] || error "lru_size changed $before != $now"
28494 }
28495 run_test 816 "do not reset lru_resize on idle reconnect"
28496
28497 cleanup_817() {
28498         umount $tmpdir
28499         exportfs -u localhost:$DIR/nfsexp
28500         rm -rf $DIR/nfsexp
28501 }
28502
28503 test_817() {
28504         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28505
28506         mkdir -p $DIR/nfsexp
28507         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28508                 error "failed to export nfs"
28509
28510         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28511         stack_trap cleanup_817 EXIT
28512
28513         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28514                 error "failed to mount nfs to $tmpdir"
28515
28516         cp /bin/true $tmpdir
28517         $DIR/nfsexp/true || error "failed to execute 'true' command"
28518 }
28519 run_test 817 "nfsd won't cache write lock for exec file"
28520
28521 test_818() {
28522         test_mkdir -i0 -c1 $DIR/$tdir
28523         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28524         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28525         stop $SINGLEMDS
28526
28527         # restore osp-syn threads
28528         stack_trap "fail $SINGLEMDS"
28529
28530         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28531         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28532         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28533                 error "start $SINGLEMDS failed"
28534         rm -rf $DIR/$tdir
28535
28536         local testid=$(echo $TESTNAME | tr '_' ' ')
28537
28538         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28539                 grep "run LFSCK" || error "run LFSCK is not suggested"
28540 }
28541 run_test 818 "unlink with failed llog"
28542
28543 test_819a() {
28544         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28545         cancel_lru_locks osc
28546         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28547         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28548         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28549         rm -f $TDIR/$tfile
28550 }
28551 run_test 819a "too big niobuf in read"
28552
28553 test_819b() {
28554         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28555         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28557         cancel_lru_locks osc
28558         sleep 1
28559         rm -f $TDIR/$tfile
28560 }
28561 run_test 819b "too big niobuf in write"
28562
28563
28564 function test_820_start_ost() {
28565         sleep 5
28566
28567         for num in $(seq $OSTCOUNT); do
28568                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28569         done
28570 }
28571
28572 test_820() {
28573         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28574
28575         mkdir $DIR/$tdir
28576         umount_client $MOUNT || error "umount failed"
28577         for num in $(seq $OSTCOUNT); do
28578                 stop ost$num
28579         done
28580
28581         # mount client with no active OSTs
28582         # so that the client can't initialize max LOV EA size
28583         # from OSC notifications
28584         mount_client $MOUNT || error "mount failed"
28585         # delay OST starting to keep this 0 max EA size for a while
28586         test_820_start_ost &
28587
28588         # create a directory on MDS2
28589         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28590                 error "Failed to create directory"
28591         # open intent should update default EA size
28592         # see mdc_update_max_ea_from_body()
28593         # notice this is the very first RPC to MDS2
28594         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28595         ret=$?
28596         echo $out
28597         # With SSK, this situation can lead to -EPERM being returned.
28598         # In that case, simply retry.
28599         if [ $ret -ne 0 ] && $SHARED_KEY; then
28600                 if echo "$out" | grep -q "not permitted"; then
28601                         cp /etc/services $DIR/$tdir/mds2
28602                         ret=$?
28603                 fi
28604         fi
28605         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28606 }
28607 run_test 820 "update max EA from open intent"
28608
28609 test_823() {
28610         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28611         local OST_MAX_PRECREATE=20000
28612
28613         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28614                 skip "Need MDS version at least 2.14.56"
28615
28616         save_lustre_params mds1 \
28617                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28618         do_facet $SINGLEMDS "$LCTL set_param -n \
28619                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28620         do_facet $SINGLEMDS "$LCTL set_param -n \
28621                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28622
28623         stack_trap "restore_lustre_params < $p; rm $p"
28624
28625         do_facet $SINGLEMDS "$LCTL set_param -n \
28626                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28627
28628         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28629                       osp.$FSNAME-OST0000*MDT0000.create_count")
28630         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28631                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28632         local expect_count=$(((($max/2)/256) * 256))
28633
28634         log "setting create_count to 100200:"
28635         log " -result- count: $count with max: $max, expecting: $expect_count"
28636
28637         [[ $count -eq expect_count ]] ||
28638                 error "Create count not set to max precreate."
28639 }
28640 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28641
28642 test_831() {
28643         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28644                 skip "Need MDS version 2.14.56"
28645
28646         local sync_changes=$(do_facet $SINGLEMDS \
28647                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28648
28649         [ "$sync_changes" -gt 100 ] &&
28650                 skip "Sync changes $sync_changes > 100 already"
28651
28652         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28653
28654         $LFS mkdir -i 0 $DIR/$tdir
28655         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28656
28657         save_lustre_params mds1 \
28658                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28659         save_lustre_params mds1 \
28660                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28661
28662         do_facet mds1 "$LCTL set_param -n \
28663                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28664                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28665         stack_trap "restore_lustre_params < $p" EXIT
28666
28667         createmany -o $DIR/$tdir/f- 1000
28668         unlinkmany $DIR/$tdir/f- 1000 &
28669         local UNLINK_PID=$!
28670
28671         while sleep 1; do
28672                 sync_changes=$(do_facet mds1 \
28673                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28674                 # the check in the code is racy, fail the test
28675                 # if the value above the limit by 10.
28676                 [ $sync_changes -gt 110 ] && {
28677                         kill -2 $UNLINK_PID
28678                         wait
28679                         error "osp changes throttling failed, $sync_changes>110"
28680                 }
28681                 kill -0 $UNLINK_PID 2> /dev/null || break
28682         done
28683         wait
28684 }
28685 run_test 831 "throttling unlink/setattr queuing on OSP"
28686
28687 #
28688 # tests that do cleanup/setup should be run at the end
28689 #
28690
28691 test_900() {
28692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28693         local ls
28694
28695         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28696         $LCTL set_param fail_loc=0x903
28697
28698         cancel_lru_locks MGC
28699
28700         FAIL_ON_ERROR=true cleanup
28701         FAIL_ON_ERROR=true setup
28702 }
28703 run_test 900 "umount should not race with any mgc requeue thread"
28704
28705 # LUS-6253/LU-11185
28706 test_901() {
28707         local old
28708         local count
28709         local oldc
28710         local newc
28711         local olds
28712         local news
28713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28714
28715         # some get_param have a bug to handle dot in param name
28716         cancel_lru_locks MGC
28717         old=$(mount -t lustre | wc -l)
28718         # 1 config+sptlrpc
28719         # 2 params
28720         # 3 nodemap
28721         # 4 IR
28722         old=$((old * 4))
28723         oldc=0
28724         count=0
28725         while [ $old -ne $oldc ]; do
28726                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28727                 sleep 1
28728                 ((count++))
28729                 if [ $count -ge $TIMEOUT ]; then
28730                         error "too large timeout"
28731                 fi
28732         done
28733         umount_client $MOUNT || error "umount failed"
28734         mount_client $MOUNT || error "mount failed"
28735         cancel_lru_locks MGC
28736         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28737
28738         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28739
28740         return 0
28741 }
28742 run_test 901 "don't leak a mgc lock on client umount"
28743
28744 # LU-13377
28745 test_902() {
28746         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28747                 skip "client does not have LU-13377 fix"
28748         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28749         $LCTL set_param fail_loc=0x1415
28750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28751         cancel_lru_locks osc
28752         rm -f $DIR/$tfile
28753 }
28754 run_test 902 "test short write doesn't hang lustre"
28755
28756 # LU-14711
28757 test_903() {
28758         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28759         echo "blah" > $DIR/${tfile}-2
28760         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28761         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28762         $LCTL set_param fail_loc=0x417 fail_val=20
28763
28764         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28765         sleep 1 # To start the destroy
28766         wait_destroy_complete 150 || error "Destroy taking too long"
28767         cat $DIR/$tfile > /dev/null || error "Evicted"
28768 }
28769 run_test 903 "Test long page discard does not cause evictions"
28770
28771 test_904() {
28772         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28773         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28774                 grep -q project || skip "skip project quota not supported"
28775
28776         local testfile="$DIR/$tdir/$tfile"
28777         local xattr="trusted.projid"
28778         local projid
28779         local mdts=$(comma_list $(mdts_nodes))
28780         local saved=$(do_facet mds1 $LCTL get_param -n \
28781                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28782
28783         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28784         stack_trap "do_nodes $mdts $LCTL set_param \
28785                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28786
28787         mkdir -p $DIR/$tdir
28788         touch $testfile
28789         #hide projid xattr on server
28790         $LFS project -p 1 $testfile ||
28791                 error "set $testfile project id failed"
28792         getfattr -m - $testfile | grep $xattr &&
28793                 error "do not show trusted.projid when disabled on server"
28794         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28795         #should be hidden when projid is 0
28796         $LFS project -p 0 $testfile ||
28797                 error "set $testfile project id failed"
28798         getfattr -m - $testfile | grep $xattr &&
28799                 error "do not show trusted.projid with project ID 0"
28800
28801         #still can getxattr explicitly
28802         projid=$(getfattr -n $xattr $testfile |
28803                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28804         [ $projid == "0" ] ||
28805                 error "projid expected 0 not $projid"
28806
28807         #set the projid via setxattr
28808         setfattr -n $xattr -v "1000" $testfile ||
28809                 error "setattr failed with $?"
28810         projid=($($LFS project $testfile))
28811         [ ${projid[0]} == "1000" ] ||
28812                 error "projid expected 1000 not $projid"
28813
28814         #check the new projid via getxattr
28815         $LFS project -p 1001 $testfile ||
28816                 error "set $testfile project id failed"
28817         getfattr -m - $testfile | grep $xattr ||
28818                 error "should show trusted.projid when project ID != 0"
28819         projid=$(getfattr -n $xattr $testfile |
28820                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28821         [ $projid == "1001" ] ||
28822                 error "projid expected 1001 not $projid"
28823
28824         #try to set invalid projid
28825         setfattr -n $xattr -v "4294967295" $testfile &&
28826                 error "set invalid projid should fail"
28827
28828         #remove the xattr means setting projid to 0
28829         setfattr -x $xattr $testfile ||
28830                 error "setfattr failed with $?"
28831         projid=($($LFS project $testfile))
28832         [ ${projid[0]} == "0" ] ||
28833                 error "projid expected 0 not $projid"
28834
28835         #should be hidden when parent has inherit flag and same projid
28836         $LFS project -srp 1002 $DIR/$tdir ||
28837                 error "set $tdir project id failed"
28838         getfattr -m - $testfile | grep $xattr &&
28839                 error "do not show trusted.projid with inherit flag"
28840
28841         #still can getxattr explicitly
28842         projid=$(getfattr -n $xattr $testfile |
28843                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28844         [ $projid == "1002" ] ||
28845                 error "projid expected 1002 not $projid"
28846 }
28847 run_test 904 "virtual project ID xattr"
28848
28849 # LU-8582
28850 test_905() {
28851         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28852                 skip "lustre < 2.8.54 does not support ladvise"
28853
28854         remote_ost_nodsh && skip "remote OST with nodsh"
28855         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28856
28857         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28858
28859         #define OBD_FAIL_OST_OPCODE 0x253
28860         # OST_LADVISE = 21
28861         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28862         $LFS ladvise -a willread $DIR/$tfile &&
28863                 error "unexpected success of ladvise with fault injection"
28864         $LFS ladvise -a willread $DIR/$tfile |&
28865                 grep -q "Operation not supported"
28866         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28867 }
28868 run_test 905 "bad or new opcode should not stuck client"
28869
28870 test_906() {
28871         grep -q io_uring_setup /proc/kallsyms ||
28872                 skip "Client OS does not support io_uring I/O engine"
28873         io_uring_probe || skip "kernel does not support io_uring fully"
28874         which fio || skip_env "no fio installed"
28875         fio --enghelp | grep -q io_uring ||
28876                 skip_env "fio does not support io_uring I/O engine"
28877
28878         local file=$DIR/$tfile
28879         local ioengine="io_uring"
28880         local numjobs=2
28881         local size=50M
28882
28883         fio --name=seqwrite --ioengine=$ioengine        \
28884                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28885                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28886                 error "fio seqwrite $file failed"
28887
28888         fio --name=seqread --ioengine=$ioengine \
28889                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28890                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28891                 error "fio seqread $file failed"
28892
28893         rm -f $file || error "rm -f $file failed"
28894 }
28895 run_test 906 "Simple test for io_uring I/O engine via fio"
28896
28897 complete $SECONDS
28898 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28899 check_and_cleanup_lustre
28900 if [ "$I_MOUNTED" != "yes" ]; then
28901         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28902 fi
28903 exit_status